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