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 Implementation of the environment variable support.
22 : *
23 : * This file implements a variable which retrieves its value from the
24 : * process environment. For example, you could retrieve the path to
25 : * the HOME directory.
26 : *
27 : * This is often used to distinguish between runs.
28 : */
29 :
30 : // self
31 : //
32 : #include "snaplogger/exception.h"
33 : #include "snaplogger/map_diagnostic.h"
34 : #include "snaplogger/variable.h"
35 :
36 :
37 : // cppthread lib
38 : //
39 : #include <cppthread/thread.h>
40 :
41 :
42 : // C lib
43 : //
44 : #include <netdb.h>
45 : #include <sys/param.h>
46 :
47 :
48 : // last include
49 : //
50 : #include <snapdev/poison.h>
51 :
52 :
53 :
54 : namespace snaplogger
55 : {
56 :
57 :
58 : namespace
59 : {
60 :
61 :
62 129 : DEFINE_LOGGER_VARIABLE(hostname)
63 : {
64 92 : auto params(get_params());
65 92 : if(params.size() > 0
66 46 : && params[0]->get_name() == "running")
67 : {
68 0 : char host[HOST_NAME_MAX + 2];
69 0 : if(gethostname(host, HOST_NAME_MAX + 1) == 0)
70 : {
71 0 : host[HOST_NAME_MAX + 1] = '\0'; // make sure it's null terminated
72 0 : value += host;
73 : }
74 : }
75 : else
76 : {
77 46 : value += msg.get_environment()->get_hostname();
78 : }
79 :
80 46 : variable::process_value(msg, value);
81 41 : }
82 :
83 :
84 8 : DEFINE_LOGGER_VARIABLE(hostbyname)
85 : {
86 0 : auto params(get_params());
87 0 : if(params.empty())
88 : {
89 0 : throw invalid_variable("the ${hostbyname:...} variable must have a name parameter.");
90 : }
91 0 : if(params[0]->get_name() != "name")
92 : {
93 0 : throw invalid_variable("the ${hostbyname:...} variable first parameter must be its name parameter.");
94 : }
95 0 : auto hostname(params[0]->get_value());
96 0 : if(hostname.empty())
97 : {
98 0 : throw invalid_variable("the ${hostbyname:...} variable first parameter must be its non-empty name.");
99 : }
100 0 : hostent * h(gethostbyname(hostname.c_str()));
101 0 : if(h != nullptr)
102 : {
103 0 : value += h->h_name;
104 : }
105 : else
106 : {
107 0 : value += "<host " + std::string(h->h_name) + " not found>";
108 : }
109 :
110 0 : variable::process_value(msg, value);
111 0 : }
112 :
113 :
114 8 : DEFINE_LOGGER_VARIABLE(domainname)
115 : {
116 0 : auto params(get_params());
117 0 : if(params.size() > 0
118 0 : && params[0]->get_name() == "running")
119 : {
120 0 : char domain[HOST_NAME_MAX + 2];
121 0 : if(getdomainname(domain, HOST_NAME_MAX + 1) == 0)
122 : {
123 0 : domain[HOST_NAME_MAX + 1] = '\0'; // make sure it's null terminated
124 0 : value += domain;
125 : }
126 : }
127 : else
128 : {
129 0 : value += msg.get_environment()->get_domainname();
130 : }
131 :
132 0 : variable::process_value(msg, value);
133 0 : }
134 :
135 :
136 8 : DEFINE_LOGGER_VARIABLE(boot_id)
137 : {
138 0 : auto params(get_params());
139 0 : if(params.size() > 0
140 0 : && params[0]->get_name() == "running")
141 : {
142 0 : value += cppthread::get_boot_id();
143 : }
144 : else
145 : {
146 0 : value += msg.get_environment()->get_boot_id();
147 : }
148 :
149 0 : variable::process_value(msg, value);
150 0 : }
151 :
152 :
153 19 : DEFINE_LOGGER_VARIABLE(pid)
154 : {
155 4 : auto params(get_params());
156 4 : if(params.size() > 0
157 2 : && params[0]->get_name() == "running")
158 : {
159 1 : value += std::to_string(getpid());
160 : }
161 : else
162 : {
163 1 : value += std::to_string(msg.get_environment()->get_pid());
164 : }
165 :
166 2 : variable::process_value(msg, value);
167 2 : }
168 :
169 :
170 8 : DEFINE_LOGGER_VARIABLE(tid)
171 : {
172 0 : auto params(get_params());
173 0 : if(params.size() > 0
174 0 : && params[0]->get_name() == "running")
175 : {
176 0 : value += std::to_string(cppthread::gettid());
177 : }
178 : else
179 : {
180 0 : value += std::to_string(msg.get_environment()->get_tid());
181 : }
182 :
183 0 : variable::process_value(msg, value);
184 0 : }
185 :
186 :
187 8 : DEFINE_LOGGER_VARIABLE(threadname)
188 : {
189 0 : auto params(get_params());
190 0 : if(params.size() > 0
191 0 : && params[0]->get_name() == "running")
192 : {
193 : // we assume that the user has a map_diagnostic with the name
194 : // "threadname"; this is going to be automatic in our own snap_thread
195 : // implementation, any others would have to be done manually
196 : //
197 0 : map_diagnostics_t diag(get_map_diagnostics());
198 0 : std::string const tid(std::to_string(cppthread::gettid()));
199 0 : auto it(diag.find("threadname#" + tid));
200 0 : if(it != diag.end())
201 : {
202 0 : value += it->second;
203 : }
204 : }
205 : else
206 : {
207 0 : value += msg.get_environment()->get_threadname();
208 : }
209 :
210 0 : variable::process_value(msg, value);
211 0 : }
212 :
213 :
214 : }
215 : // no name namespace
216 :
217 :
218 6 : } // snaplogger namespace
219 : // vim: ts=4 sw=4 et
|