Line data Source code
1 : // Copyright (c) 2013-2021 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 : // C++ lib
32 : //
33 : #include <iostream>
34 :
35 :
36 : // C lib
37 : //
38 : #include <syslog.h>
39 :
40 :
41 : // last include
42 : //
43 : #include <snapdev/poison.h>
44 :
45 :
46 :
47 : namespace snaplogger
48 : {
49 :
50 :
51 :
52 : namespace
53 : {
54 :
55 :
56 8 : APPENDER_FACTORY(syslog);
57 :
58 :
59 : struct facility_by_name
60 : {
61 : char const * const f_name = nullptr;
62 : int const f_facility = LOG_USER;
63 : };
64 :
65 :
66 : constexpr facility_by_name g_facility_by_name[] =
67 : {
68 : { "auth", LOG_AUTH },
69 : { "authpriv", LOG_AUTHPRIV },
70 : { "cron", LOG_CRON },
71 : { "daemon", LOG_DAEMON },
72 : { "ftp", LOG_FTP },
73 : { "kern", LOG_KERN },
74 : { "local0", LOG_LOCAL0 },
75 : { "local1", LOG_LOCAL1 },
76 : { "local2", LOG_LOCAL2 },
77 : { "local3", LOG_LOCAL3 },
78 : { "local4", LOG_LOCAL4 },
79 : { "local5", LOG_LOCAL5 },
80 : { "local6", LOG_LOCAL6 },
81 : { "local7", LOG_LOCAL7 },
82 : { "lpr", LOG_LPR },
83 : { "mail", LOG_MAIL },
84 : { "news", LOG_NEWS },
85 : { "syslog", LOG_SYSLOG },
86 : { "user", LOG_USER },
87 : { "uucp", LOG_UUCP }
88 : };
89 :
90 :
91 :
92 :
93 : }
94 : // no name namespace
95 :
96 :
97 :
98 0 : syslog_appender::syslog_appender(std::string const name)
99 0 : : appender(name, "syslog")
100 : {
101 0 : }
102 :
103 :
104 0 : syslog_appender::~syslog_appender()
105 : {
106 0 : }
107 :
108 :
109 0 : bool syslog_appender::unique() const
110 : {
111 0 : return true;
112 : }
113 :
114 :
115 0 : void syslog_appender::set_config(advgetopt::getopt const & opts)
116 : {
117 0 : closelog();
118 :
119 0 : appender::set_config(opts);
120 :
121 : // FACILITY
122 : //
123 0 : int facility(LOG_USER);
124 0 : std::string const facility_field(get_name() + "::facility");
125 0 : if(opts.is_defined(facility_field))
126 : {
127 0 : std::string const facility_name(opts.get_string(facility_field));
128 0 : int i(0);
129 0 : int j(sizeof(g_facility_by_name) / sizeof(g_facility_by_name[0]));
130 0 : while(i < j)
131 : {
132 0 : int const p(i + (j - i) / 2);
133 0 : int const r(facility_name.compare(g_facility_by_name[p].f_name));
134 0 : if(r == 0)
135 : {
136 0 : facility = g_facility_by_name[p].f_facility;
137 0 : break;
138 : }
139 0 : if(r < 0)
140 : {
141 0 : i = p + 1;
142 : }
143 : else // if(r > 0)
144 : {
145 0 : j = p;
146 : }
147 : }
148 : }
149 :
150 : // IDENTITY
151 : //
152 0 : std::string const identity_field(get_name() + "::identity");
153 0 : if(opts.is_defined(identity_field))
154 : {
155 0 : f_identity = opts.get_string(identity_field);
156 : }
157 :
158 : // FALLBACK TO CONSOLE
159 : //
160 0 : int options(LOG_NDELAY | LOG_PID);
161 0 : std::string const fallback_to_console_field(get_name() + "::fallback_to_console");
162 0 : if(opts.is_defined(fallback_to_console_field))
163 : {
164 0 : if(opts.get_string(fallback_to_console_field) == "true")
165 : {
166 0 : options |= LOG_CONS;
167 : }
168 : }
169 :
170 : // open the log immediately
171 : //
172 0 : openlog(f_identity.c_str(), options, facility);
173 0 : }
174 :
175 :
176 0 : void syslog_appender::process_message(message const & msg, std::string const & formatted_message)
177 : {
178 0 : int priority(LOG_INFO);
179 0 : severity_t const sev(msg.get_severity());
180 0 : if(sev <= severity_t::SEVERITY_DEBUG)
181 : {
182 0 : priority = LOG_DEBUG;
183 : }
184 0 : else if(sev <= severity_t::SEVERITY_INFORMATION)
185 : {
186 0 : priority = LOG_INFO;
187 : }
188 0 : else if(sev <= severity_t::SEVERITY_MINOR)
189 : {
190 0 : priority = LOG_NOTICE;
191 : }
192 0 : else if(sev <= severity_t::SEVERITY_MAJOR)
193 : {
194 0 : priority = LOG_WARNING;
195 : }
196 0 : else if(sev <= severity_t::SEVERITY_ERROR)
197 : {
198 0 : priority = LOG_ERR;
199 : }
200 0 : else if(sev <= severity_t::SEVERITY_CRITICAL)
201 : {
202 0 : priority = LOG_CRIT;
203 : }
204 0 : else if(sev <= severity_t::SEVERITY_ALERT)
205 : {
206 0 : priority = LOG_ALERT;
207 : }
208 : else
209 : {
210 0 : priority = LOG_EMERG;
211 : }
212 :
213 0 : syslog(priority, "%s", formatted_message.c_str());
214 0 : }
215 :
216 :
217 :
218 :
219 :
220 6 : } // snaplogger namespace
221 : // vim: ts=4 sw=4 et
|