Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2022 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #include "EnvVariableParser.h"
21 : #include "LogFileHandle.h"
22 : #include <algorithm>
23 : #include <string>
24 : #include <unistd.h>
25 : #include <vector>
26 :
27 : namespace
28 : {
29 35 : std::string getRialtoDebug()
30 : {
31 35 : const char *kDebugVar = getenv("RIALTO_DEBUG");
32 35 : if (kDebugVar)
33 : {
34 34 : return std::string(kDebugVar);
35 : }
36 1 : return "";
37 : }
38 :
39 35 : std::string getRialtoConsoleLog()
40 : {
41 35 : const char *kDebugVar = getenv("RIALTO_CONSOLE_LOG");
42 35 : if (kDebugVar)
43 : {
44 34 : return std::string(kDebugVar);
45 : }
46 1 : return "";
47 : }
48 :
49 35 : std::string getRialtoLogPath()
50 : {
51 35 : const char *kLogPathEnvVar = getenv("RIALTO_LOG_PATH");
52 35 : if (kLogPathEnvVar)
53 : {
54 1 : return std::string(kLogPathEnvVar);
55 : }
56 34 : return "";
57 : }
58 :
59 54 : inline bool isNumber(const std::string &str)
60 : {
61 108 : return std::find_if(str.begin(), str.end(), [](unsigned char c) { return !std::isdigit(c); }) == str.end();
62 : }
63 :
64 34 : std::vector<std::string> split(std::string s, const std::string &delimiter)
65 : {
66 34 : std::vector<std::string> result;
67 34 : size_t pos = 0;
68 68 : while ((pos = s.find(delimiter)) != std::string::npos)
69 : {
70 34 : result.push_back(s.substr(0, pos));
71 34 : s.erase(0, pos + delimiter.length());
72 : }
73 34 : result.push_back(s);
74 34 : return result;
75 : }
76 :
77 11 : std::map<std::string, int> parseEnvVar(const std::string &envVar)
78 : {
79 11 : std::map<std::string, int> flagValues;
80 22 : auto componentsWithLevels{split(envVar, ";")};
81 34 : for (const auto &item : componentsWithLevels)
82 : {
83 46 : auto componentWithLevel{split(item, ":")};
84 23 : if (componentWithLevel.size() != 2 || !isNumber(componentWithLevel[1]))
85 4 : continue;
86 19 : flagValues[componentWithLevel[0]] = std::stoi(componentWithLevel[1]);
87 23 : }
88 22 : return flagValues;
89 11 : }
90 :
91 173 : RIALTO_DEBUG_LEVEL levelFromNumber(int level)
92 : {
93 173 : switch (level)
94 : {
95 35 : case 0:
96 35 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL);
97 28 : case 1:
98 28 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR);
99 0 : case 2:
100 0 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR | RIALTO_DEBUG_LEVEL_WARNING);
101 0 : case 3:
102 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR | RIALTO_DEBUG_LEVEL_WARNING |
103 0 : RIALTO_DEBUG_LEVEL_MILESTONE);
104 0 : case 4:
105 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR | RIALTO_DEBUG_LEVEL_WARNING |
106 0 : RIALTO_DEBUG_LEVEL_MILESTONE | RIALTO_DEBUG_LEVEL_INFO);
107 110 : case 5:
108 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR | RIALTO_DEBUG_LEVEL_WARNING |
109 110 : RIALTO_DEBUG_LEVEL_MILESTONE | RIALTO_DEBUG_LEVEL_INFO | RIALTO_DEBUG_LEVEL_DEBUG);
110 : }
111 0 : return RIALTO_DEBUG_LEVEL_DEFAULT;
112 : }
113 :
114 9 : RIALTO_COMPONENT componentFromStr(const std::string &component)
115 : {
116 9 : if ("client" == component)
117 : {
118 0 : return RIALTO_COMPONENT_CLIENT;
119 : }
120 9 : if ("sessionserver" == component)
121 : {
122 0 : return RIALTO_COMPONENT_SERVER;
123 : }
124 9 : if ("ipc" == component)
125 : {
126 8 : return RIALTO_COMPONENT_IPC;
127 : }
128 1 : if ("servermanager" == component)
129 : {
130 0 : return RIALTO_COMPONENT_SERVER_MANAGER;
131 : }
132 1 : if ("common" == component)
133 : {
134 0 : return RIALTO_COMPONENT_COMMON;
135 : }
136 1 : return RIALTO_COMPONENT_LAST;
137 : }
138 : } // namespace
139 :
140 : namespace firebolt::rialto::logging
141 : {
142 35 : EnvVariableParser::EnvVariableParser()
143 35 : : m_debugLevels{{RIALTO_COMPONENT_CLIENT, RIALTO_DEBUG_LEVEL_DEFAULT},
144 : {RIALTO_COMPONENT_SERVER, RIALTO_DEBUG_LEVEL_DEFAULT},
145 : {RIALTO_COMPONENT_IPC, RIALTO_DEBUG_LEVEL_DEFAULT},
146 : {RIALTO_COMPONENT_SERVER_MANAGER, RIALTO_DEBUG_LEVEL_DEFAULT},
147 : {RIALTO_COMPONENT_COMMON, RIALTO_DEBUG_LEVEL_DEFAULT}},
148 35 : m_logToConsole{false}, m_logFilePath{getRialtoLogPath()}
149 : {
150 35 : configureRialtoDebug();
151 35 : configureRialtoConsoleLog();
152 35 : configureFileLogging();
153 : }
154 :
155 35 : void EnvVariableParser::configureRialtoDebug()
156 : {
157 35 : std::string debugFlagEnvVar = getRialtoDebug();
158 35 : if (debugFlagEnvVar.empty())
159 1 : return;
160 34 : if (isNumber(debugFlagEnvVar))
161 : {
162 23 : int level = std::stoi(debugFlagEnvVar);
163 138 : for (auto &elem : m_debugLevels)
164 115 : elem.second = levelFromNumber(level);
165 23 : return;
166 : }
167 11 : auto flagValues{parseEnvVar(debugFlagEnvVar)};
168 11 : auto defaultFlagIter = flagValues.find("*");
169 11 : if (defaultFlagIter != flagValues.end())
170 : {
171 60 : for (auto &elem : m_debugLevels)
172 50 : elem.second = levelFromNumber(defaultFlagIter->second);
173 10 : flagValues.erase(defaultFlagIter);
174 : }
175 20 : for (const auto &value : flagValues)
176 : {
177 9 : auto currentLevelIter = m_debugLevels.find(componentFromStr(value.first));
178 9 : if (currentLevelIter != m_debugLevels.end())
179 : {
180 8 : currentLevelIter->second = levelFromNumber(value.second);
181 : }
182 : }
183 35 : }
184 :
185 35 : void EnvVariableParser::configureRialtoConsoleLog()
186 : {
187 35 : std::string debugFlagEnvVar = getRialtoConsoleLog();
188 35 : if (debugFlagEnvVar == "1")
189 : {
190 31 : m_logToConsole = true;
191 : }
192 15 : }
193 :
194 35 : void EnvVariableParser::configureFileLogging()
195 : {
196 35 : if (isFileLoggingEnabled())
197 : {
198 1 : LogFileHandle::instance().init(m_logFilePath);
199 : }
200 35 : }
201 :
202 62 : RIALTO_DEBUG_LEVEL EnvVariableParser::getLevel(const RIALTO_COMPONENT &component) const
203 : {
204 62 : if (RIALTO_COMPONENT_EXTERNAL == component)
205 : {
206 8 : return RIALTO_DEBUG_LEVEL_EXTERNAL;
207 : }
208 54 : auto levelIter = m_debugLevels.find(component);
209 54 : if (levelIter == m_debugLevels.end())
210 3 : return RIALTO_DEBUG_LEVEL_DEFAULT;
211 51 : return levelIter->second;
212 : }
213 :
214 8783 : bool EnvVariableParser::isConsoleLoggingEnabled() const
215 : {
216 8783 : return m_logToConsole;
217 : }
218 :
219 8814 : bool EnvVariableParser::isFileLoggingEnabled() const
220 : {
221 8814 : return !m_logFilePath.empty();
222 : }
223 : } // namespace firebolt::rialto::logging
|