Add a syslog() based sink for Linux.
This commit introduce a new sink: syslog_sink. This sink is Linux only, and will write log entries to the system logger, using the syslog() library call. It is instanciable using spdlog::syslog_logger(name). Note that the suffix _st or _mt is not present, as syslog() is thread-safe. I also applied @gabime reviews and added license header.
This commit is contained in:
		@@ -64,6 +64,10 @@ int main(int, char* [])
 | 
			
		||||
        SPDLOG_TRACE(file_logger, "This is a trace message (only #ifdef _DEBUG)", 123);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	#ifdef __linux__
 | 
			
		||||
	auto syslog_logger = spd::syslog_logger("syslog");
 | 
			
		||||
	syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!");
 | 
			
		||||
	#endif
 | 
			
		||||
    }
 | 
			
		||||
    catch (const spd::spdlog_ex& ex)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -46,17 +46,17 @@ namespace level
 | 
			
		||||
{
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    TRACE,
 | 
			
		||||
    DEBUG,
 | 
			
		||||
    INFO,
 | 
			
		||||
    NOTICE,
 | 
			
		||||
    WARN,
 | 
			
		||||
    ERR,
 | 
			
		||||
    CRITICAL,
 | 
			
		||||
    ALERT,
 | 
			
		||||
    EMERG,
 | 
			
		||||
    ALWAYS,
 | 
			
		||||
    OFF
 | 
			
		||||
    TRACE    = 0,
 | 
			
		||||
    DEBUG    = 1,
 | 
			
		||||
    INFO     = 2,
 | 
			
		||||
    NOTICE   = 3,
 | 
			
		||||
    WARN     = 4, 
 | 
			
		||||
    ERR      = 5,
 | 
			
		||||
    CRITICAL = 6,
 | 
			
		||||
    ALERT    = 7,
 | 
			
		||||
    EMERG    = 8,
 | 
			
		||||
    ALWAYS   = 9,
 | 
			
		||||
    OFF      = 10
 | 
			
		||||
} level_enum;
 | 
			
		||||
 | 
			
		||||
static const char* level_names[] { "trace", "debug", "info", "notice", "warning", "error", "critical",
 | 
			
		||||
 
 | 
			
		||||
@@ -126,7 +126,7 @@ public:
 | 
			
		||||
        swap(first._dev, second._dev);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string str()
 | 
			
		||||
    std::string str() const
 | 
			
		||||
    {
 | 
			
		||||
        auto& buffer = _dev.buf();
 | 
			
		||||
        const char*data = buffer.data();
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@
 | 
			
		||||
#include "registry.h"
 | 
			
		||||
#include "../sinks/file_sinks.h"
 | 
			
		||||
#include "../sinks/stdout_sinks.h"
 | 
			
		||||
#include "../sinks/syslog_sink.h"
 | 
			
		||||
 | 
			
		||||
inline std::shared_ptr<spdlog::logger> spdlog::get(const std::string& name)
 | 
			
		||||
{
 | 
			
		||||
@@ -81,6 +82,13 @@ inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::strin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Create syslog logger
 | 
			
		||||
inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& logger_name)
 | 
			
		||||
{
 | 
			
		||||
    return create<spdlog::sinks::syslog_sink>(logger_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks)
 | 
			
		||||
{
 | 
			
		||||
    return details::registry::instance().create(logger_name, sinks);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										92
									
								
								include/spdlog/sinks/syslog_sink.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								include/spdlog/sinks/syslog_sink.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*************************************************************************/
 | 
			
		||||
/* spdlog - an extremely fast and easy to use c++11 logging library.     */
 | 
			
		||||
/* Copyright (c) 2014 Gabi Melman.                                       */
 | 
			
		||||
/*                                                                       */
 | 
			
		||||
/* Permission is hereby granted, free of charge, to any person obtaining */
 | 
			
		||||
/* a copy of this software and associated documentation files (the       */
 | 
			
		||||
/* "Software"), to deal in the Software without restriction, including   */
 | 
			
		||||
/* without limitation the rights to use, copy, modify, merge, publish,   */
 | 
			
		||||
/* distribute, sublicense, and/or sell copies of the Software, and to    */
 | 
			
		||||
/* permit persons to whom the Software is furnished to do so, subject to */
 | 
			
		||||
/* the following conditions:                                             */
 | 
			
		||||
/*                                                                       */
 | 
			
		||||
/* The above copyright notice and this permission notice shall be        */
 | 
			
		||||
/* included in all copies or substantial portions of the Software.       */
 | 
			
		||||
/*                                                                       */
 | 
			
		||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
 | 
			
		||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
 | 
			
		||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
 | 
			
		||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
 | 
			
		||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
 | 
			
		||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
 | 
			
		||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 | 
			
		||||
/*************************************************************************/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include "./sink.h"
 | 
			
		||||
#include "../formatter.h"
 | 
			
		||||
#include "../common.h"
 | 
			
		||||
#include "../details/log_msg.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace spdlog
 | 
			
		||||
{
 | 
			
		||||
  namespace sinks
 | 
			
		||||
  {
 | 
			
		||||
    /**
 | 
			
		||||
     * Sink that write to syslog using the `syscall()` library call.
 | 
			
		||||
     *
 | 
			
		||||
     * Locking is not needed, as `syslog()` itself is thread-safe.
 | 
			
		||||
     */
 | 
			
		||||
    class syslog_sink : public sink
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
      syslog_sink()
 | 
			
		||||
	{
 | 
			
		||||
	  _priorities[static_cast<int>(level::TRACE)] = LOG_DEBUG;
 | 
			
		||||
	  _priorities[static_cast<int>(level::DEBUG)] = LOG_DEBUG;
 | 
			
		||||
	  _priorities[static_cast<int>(level::INFO)] = LOG_INFO;
 | 
			
		||||
	  _priorities[static_cast<int>(level::NOTICE)] = LOG_NOTICE;
 | 
			
		||||
	  _priorities[static_cast<int>(level::WARN)] = LOG_WARNING;
 | 
			
		||||
	  _priorities[static_cast<int>(level::ERR)] = LOG_ERR;
 | 
			
		||||
	  _priorities[static_cast<int>(level::CRITICAL)] = LOG_CRIT;
 | 
			
		||||
	  _priorities[static_cast<int>(level::ALERT)] = LOG_ALERT;
 | 
			
		||||
	  _priorities[static_cast<int>(level::EMERG)] = LOG_EMERG;
 | 
			
		||||
 | 
			
		||||
	  _priorities[static_cast<int>(level::ALWAYS)] = LOG_INFO;
 | 
			
		||||
	  _priorities[static_cast<int>(level::OFF)] = LOG_INFO;
 | 
			
		||||
	}
 | 
			
		||||
      virtual ~syslog_sink() = default;
 | 
			
		||||
  
 | 
			
		||||
      syslog_sink(const syslog_sink&) = delete;
 | 
			
		||||
      syslog_sink& operator=(const syslog_sink&) = delete;
 | 
			
		||||
  
 | 
			
		||||
      void log(const details::log_msg &msg) override
 | 
			
		||||
      {
 | 
			
		||||
	syslog(syslog_prio_from_level(msg), "%s", msg.formatted.str().c_str());
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
      /**
 | 
			
		||||
       * Simply maps spdlog's log level to syslog priority level.
 | 
			
		||||
       */
 | 
			
		||||
      int syslog_prio_from_level(const details::log_msg &msg) const
 | 
			
		||||
      {
 | 
			
		||||
	return _priorities[static_cast<int>(msg.level)];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
      std::array<int, 11> _priorities;
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -68,6 +68,11 @@ std::shared_ptr<logger> stderr_logger_mt(const std::string& logger_name);
 | 
			
		||||
std::shared_ptr<logger> stderr_logger_st(const std::string& logger_name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Create a syslog logger
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
 std::shared_ptr<logger> syslog_logger(const std::string& logger_name);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Create a logger with multiple sinks
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user