123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- // 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
|