Line data Source code
1 : /*
2 : * Copyright (c) 2013-2019 Made to Order Software Corp. All Rights Reserved
3 : *
4 : * https://snapwebsites.org/project/snaplogger
5 : * contact@m2osw.com
6 : *
7 : * This program is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 2 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * This program is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License along
18 : * with this program; if not, write to the Free Software Foundation, Inc.,
19 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 : */
21 :
22 : /** \file
23 : * \brief Appenders are used to append data to somewhere.
24 : *
25 : * This file declares the base appender class.
26 : */
27 :
28 : // self
29 : //
30 : #include "snaplogger/syslog_appender.h"
31 :
32 :
33 : // C++ lib
34 : //
35 : #include <iostream>
36 :
37 :
38 : // C lib
39 : //
40 : #include <syslog.h>
41 :
42 :
43 : // last include
44 : //
45 : #include <snapdev/poison.h>
46 :
47 :
48 :
49 : namespace snaplogger
50 : {
51 :
52 :
53 :
54 : namespace
55 : {
56 :
57 :
58 8 : APPENDER_FACTORY(syslog);
59 :
60 :
61 : struct facility_by_name
62 : {
63 : char const * const f_name = nullptr;
64 : int const f_facility = LOG_USER;
65 : };
66 :
67 :
68 : constexpr facility_by_name g_facility_by_name[] =
69 : {
70 : { "auth", LOG_AUTH },
71 : { "authpriv", LOG_AUTHPRIV },
72 : { "cron", LOG_CRON },
73 : { "daemon", LOG_DAEMON },
74 : { "ftp", LOG_FTP },
75 : { "kern", LOG_KERN },
76 : { "local0", LOG_LOCAL0 },
77 : { "local1", LOG_LOCAL1 },
78 : { "local2", LOG_LOCAL2 },
79 : { "local3", LOG_LOCAL3 },
80 : { "local4", LOG_LOCAL4 },
81 : { "local5", LOG_LOCAL5 },
82 : { "local6", LOG_LOCAL6 },
83 : { "local7", LOG_LOCAL7 },
84 : { "lpr", LOG_LPR },
85 : { "mail", LOG_MAIL },
86 : { "news", LOG_NEWS },
87 : { "syslog", LOG_SYSLOG },
88 : { "user", LOG_USER },
89 : { "uucp", LOG_UUCP }
90 : };
91 :
92 :
93 :
94 :
95 : }
96 : // no name namespace
97 :
98 :
99 :
100 0 : syslog_appender::syslog_appender(std::string const name)
101 0 : : appender(name, "syslog")
102 : {
103 0 : }
104 :
105 :
106 0 : syslog_appender::~syslog_appender()
107 : {
108 0 : }
109 :
110 :
111 0 : bool syslog_appender::unique() const
112 : {
113 0 : return true;
114 : }
115 :
116 :
117 0 : void syslog_appender::set_config(advgetopt::getopt const & opts)
118 : {
119 0 : closelog();
120 :
121 0 : appender::set_config(opts);
122 :
123 : // FACILITY
124 : //
125 0 : int facility(LOG_USER);
126 0 : std::string const facility_field(get_name() + "::facility");
127 0 : if(opts.is_defined(facility_field))
128 : {
129 0 : std::string const facility_name(opts.get_string(facility_field));
130 0 : int i(0);
131 0 : int j(sizeof(g_facility_by_name) / sizeof(g_facility_by_name[0]));
132 0 : while(i < j)
133 : {
134 0 : int const p(i + (j - i) / 2);
135 0 : int const r(facility_name.compare(g_facility_by_name[p].f_name));
136 0 : if(r == 0)
137 : {
138 0 : facility = g_facility_by_name[p].f_facility;
139 0 : break;
140 : }
141 0 : if(r < 0)
142 : {
143 0 : i = p + 1;
144 : }
145 : else // if(r > 0)
146 : {
147 0 : j = p;
148 : }
149 : }
150 : }
151 :
152 : // IDENTITY
153 : //
154 0 : std::string const identity_field(get_name() + "::identity");
155 0 : if(opts.is_defined(identity_field))
156 : {
157 0 : f_identity = opts.get_string(identity_field);
158 : }
159 :
160 : // FALLBACK TO CONSOLE
161 : //
162 0 : int options(LOG_NDELAY | LOG_PID);
163 0 : std::string const fallback_to_console_field(get_name() + "::fallback_to_console");
164 0 : if(opts.is_defined(fallback_to_console_field))
165 : {
166 0 : if(opts.get_string(fallback_to_console_field) == "true")
167 : {
168 0 : options |= LOG_CONS;
169 : }
170 : }
171 :
172 : // open the log immediately
173 : //
174 0 : openlog(f_identity.c_str(), options, facility);
175 0 : }
176 :
177 :
178 0 : void syslog_appender::process_message(message const & msg, std::string const & formatted_message)
179 : {
180 0 : int priority(LOG_INFO);
181 0 : severity_t const sev(msg.get_severity());
182 0 : if(sev <= severity_t::SEVERITY_DEBUG)
183 : {
184 0 : priority = LOG_DEBUG;
185 : }
186 0 : else if(sev <= severity_t::SEVERITY_INFORMATION)
187 : {
188 0 : priority = LOG_INFO;
189 : }
190 0 : else if(sev <= severity_t::SEVERITY_MINOR)
191 : {
192 0 : priority = LOG_NOTICE;
193 : }
194 0 : else if(sev <= severity_t::SEVERITY_MAJOR)
195 : {
196 0 : priority = LOG_WARNING;
197 : }
198 0 : else if(sev <= severity_t::SEVERITY_ERROR)
199 : {
200 0 : priority = LOG_ERR;
201 : }
202 0 : else if(sev <= severity_t::SEVERITY_CRITICAL)
203 : {
204 0 : priority = LOG_CRIT;
205 : }
206 0 : else if(sev <= severity_t::SEVERITY_ALERT)
207 : {
208 0 : priority = LOG_ALERT;
209 : }
210 : else
211 : {
212 0 : priority = LOG_EMERG;
213 : }
214 :
215 0 : syslog(priority, "%s", formatted_message.c_str());
216 0 : }
217 :
218 :
219 :
220 :
221 :
222 6 : } // snaplogger namespace
223 : // vim: ts=4 sw=4 et
|