123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
- // Distributed under the MIT License (http://opensource.org/licenses/MIT)
- #pragma once
- //
- // Custom sink for mongodb
- // Building and using requires mongocxx library.
- // For building mongocxx library check the url below
- // http://mongocxx.org/mongocxx-v3/installation/
- //
- #include "spdlog/common.h"
- #include "spdlog/details/log_msg.h"
- #include "spdlog/sinks/base_sink.h"
- #include <spdlog/details/synchronous_factory.h>
- #include <bsoncxx/builder/stream/document.hpp>
- #include <bsoncxx/types.hpp>
- #include <bsoncxx/view_or_value.hpp>
- #include <mongocxx/client.hpp>
- #include <mongocxx/instance.hpp>
- #include <mongocxx/uri.hpp>
- namespace spdlog {
- namespace sinks {
- template <typename Mutex>
- class mongo_sink : public base_sink<Mutex> {
- public:
- mongo_sink(const std::string &db_name,
- const std::string &collection_name,
- const std::string &uri = "mongodb://localhost:27017") try
- : mongo_sink(std::make_shared<mongocxx::instance>(), db_name, collection_name, uri) {
- } catch (const std::exception &e) {
- throw_spdlog_ex(fmt_lib::format("Error opening database: {}", e.what()));
- }
- mongo_sink(std::shared_ptr<mongocxx::instance> instance,
- const std::string &db_name,
- const std::string &collection_name,
- const std::string &uri = "mongodb://localhost:27017")
- : instance_(std::move(instance)),
- db_name_(db_name),
- coll_name_(collection_name) {
- try {
- client_ = spdlog::details::make_unique<mongocxx::client>(mongocxx::uri{uri});
- } catch (const std::exception &e) {
- throw_spdlog_ex(fmt_lib::format("Error opening database: {}", e.what()));
- }
- }
- ~mongo_sink() { flush_(); }
- protected:
- void sink_it_(const details::log_msg &msg) override {
- using bsoncxx::builder::stream::document;
- using bsoncxx::builder::stream::finalize;
- if (client_ != nullptr) {
- auto doc = document{} << "timestamp" << bsoncxx::types::b_date(msg.time) << "level"
- << level::to_string_view(msg.level).data() << "level_num"
- << msg.level << "message"
- << std::string(msg.payload.begin(), msg.payload.end())
- << "logger_name"
- << std::string(msg.logger_name.begin(), msg.logger_name.end())
- << "thread_id" << static_cast<int>(msg.thread_id) << finalize;
- client_->database(db_name_).collection(coll_name_).insert_one(doc.view());
- }
- }
- void flush_() override {}
- private:
- std::shared_ptr<mongocxx::instance> instance_;
- std::string db_name_;
- std::string coll_name_;
- std::unique_ptr<mongocxx::client> client_ = nullptr;
- };
- #include "spdlog/details/null_mutex.h"
- #include <mutex>
- using mongo_sink_mt = mongo_sink<std::mutex>;
- using mongo_sink_st = mongo_sink<spdlog::details::null_mutex>;
- } // namespace sinks
- template <typename Factory = spdlog::synchronous_factory>
- inline std::shared_ptr<logger> mongo_logger_mt(
- const std::string &logger_name,
- const std::string &db_name,
- const std::string &collection_name,
- const std::string &uri = "mongodb://localhost:27017") {
- return Factory::template create<sinks::mongo_sink_mt>(logger_name, db_name, collection_name,
- uri);
- }
- template <typename Factory = spdlog::synchronous_factory>
- inline std::shared_ptr<logger> mongo_logger_st(
- const std::string &logger_name,
- const std::string &db_name,
- const std::string &collection_name,
- const std::string &uri = "mongodb://localhost:27017") {
- return Factory::template create<sinks::mongo_sink_st>(logger_name, db_name, collection_name,
- uri);
- }
- } // namespace spdlog
|