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 <utility>
26 : #include <vector>
27 :
28 : namespace
29 : {
30 35 : std::string getRialtoDebug()
31 : {
32 35 : const char *kDebugVar = getenv("RIALTO_DEBUG");
33 35 : if (kDebugVar)
34 : {
35 68 : return std::string(kDebugVar);
36 : }
37 2 : return "";
38 : }
39 :
40 35 : std::string getRialtoConsoleLog()
41 : {
42 35 : const char *kDebugVar = getenv("RIALTO_CONSOLE_LOG");
43 35 : if (kDebugVar)
44 : {
45 68 : return std::string(kDebugVar);
46 : }
47 2 : return "";
48 : }
49 :
50 35 : std::string getRialtoLogPath()
51 : {
52 35 : const char *kLogPathEnvVar = getenv("RIALTO_LOG_PATH");
53 35 : if (kLogPathEnvVar)
54 : {
55 2 : return std::string(kLogPathEnvVar);
56 : }
57 68 : return "";
58 : }
59 :
60 54 : inline bool isNumber(const std::string &str)
61 : {
62 108 : return std::find_if(str.begin(), str.end(), [](unsigned char c) { return !std::isdigit(c); }) == str.end();
63 : }
64 :
65 34 : std::vector<std::string> split(std::string s, const std::string &delimiter)
66 : {
67 34 : std::vector<std::string> result;
68 34 : size_t pos = 0;
69 68 : while ((pos = s.find(delimiter)) != std::string::npos)
70 : {
71 34 : result.push_back(s.substr(0, pos));
72 34 : s.erase(0, pos + delimiter.length());
73 : }
74 34 : result.push_back(std::move(s));
75 34 : return result;
76 : }
77 :
78 11 : std::map<std::string, int> parseEnvVar(const std::string &envVar)
79 : {
80 11 : std::map<std::string, int> flagValues;
81 11 : auto componentsWithLevels{split(envVar, ";")};
82 34 : for (const auto &item : componentsWithLevels)
83 : {
84 23 : auto componentWithLevel{split(item, ":")};
85 23 : if (componentWithLevel.size() != 2 || !isNumber(componentWithLevel[1]))
86 4 : continue;
87 19 : flagValues[componentWithLevel[0]] = std::stoi(componentWithLevel[1]);
88 23 : }
89 22 : return flagValues;
90 11 : }
91 :
92 173 : RIALTO_DEBUG_LEVEL levelFromNumber(int level)
93 : {
94 173 : switch (level)
95 : {
96 35 : case 0:
97 35 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL);
98 28 : case 1:
99 28 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR);
100 0 : case 2:
101 0 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR | RIALTO_DEBUG_LEVEL_WARNING);
102 0 : case 3:
103 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR | RIALTO_DEBUG_LEVEL_WARNING |
104 0 : RIALTO_DEBUG_LEVEL_MILESTONE);
105 0 : case 4:
106 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR | RIALTO_DEBUG_LEVEL_WARNING |
107 0 : RIALTO_DEBUG_LEVEL_MILESTONE | RIALTO_DEBUG_LEVEL_INFO);
108 110 : case 5:
109 : return RIALTO_DEBUG_LEVEL(RIALTO_DEBUG_LEVEL_FATAL | RIALTO_DEBUG_LEVEL_ERROR | RIALTO_DEBUG_LEVEL_WARNING |
110 110 : RIALTO_DEBUG_LEVEL_MILESTONE | RIALTO_DEBUG_LEVEL_INFO | RIALTO_DEBUG_LEVEL_DEBUG);
111 : }
112 0 : return RIALTO_DEBUG_LEVEL_DEFAULT;
113 : }
114 :
115 9 : RIALTO_COMPONENT componentFromStr(const std::string &component)
116 : {
117 9 : if ("client" == component)
118 : {
119 0 : return RIALTO_COMPONENT_CLIENT;
120 : }
121 9 : if ("sessionserver" == component)
122 : {
123 0 : return RIALTO_COMPONENT_SERVER;
124 : }
125 9 : if ("ipc" == component)
126 : {
127 8 : return RIALTO_COMPONENT_IPC;
128 : }
129 1 : if ("servermanager" == component)
130 : {
131 0 : return RIALTO_COMPONENT_SERVER_MANAGER;
132 : }
133 1 : if ("common" == component)
134 : {
135 0 : return RIALTO_COMPONENT_COMMON;
136 : }
137 1 : return RIALTO_COMPONENT_LAST;
138 : }
139 : } // namespace
140 :
141 : namespace firebolt::rialto::logging
142 : {
143 35 : EnvVariableParser::EnvVariableParser()
144 70 : : m_debugLevels{{RIALTO_COMPONENT_CLIENT, RIALTO_DEBUG_LEVEL_DEFAULT},
145 : {RIALTO_COMPONENT_SERVER, RIALTO_DEBUG_LEVEL_DEFAULT},
146 : {RIALTO_COMPONENT_IPC, RIALTO_DEBUG_LEVEL_DEFAULT},
147 : {RIALTO_COMPONENT_SERVER_MANAGER, RIALTO_DEBUG_LEVEL_DEFAULT},
148 : {RIALTO_COMPONENT_COMMON, RIALTO_DEBUG_LEVEL_DEFAULT}},
149 35 : m_logToConsole{false}, m_logFilePath{getRialtoLogPath()}
150 : {
151 35 : configureRialtoDebug();
152 35 : configureRialtoConsoleLog();
153 35 : configureFileLogging();
154 : }
155 :
156 35 : void EnvVariableParser::configureRialtoDebug()
157 : {
158 35 : std::string debugFlagEnvVar = getRialtoDebug();
159 35 : if (debugFlagEnvVar.empty())
160 1 : return;
161 34 : if (isNumber(debugFlagEnvVar))
162 : {
163 23 : int level = std::stoi(debugFlagEnvVar);
164 138 : for (auto &elem : m_debugLevels)
165 115 : elem.second = levelFromNumber(level);
166 23 : return;
167 : }
168 11 : auto flagValues{parseEnvVar(debugFlagEnvVar)};
169 11 : auto defaultFlagIter = flagValues.find("*");
170 11 : if (defaultFlagIter != flagValues.end())
171 : {
172 60 : for (auto &elem : m_debugLevels)
173 50 : elem.second = levelFromNumber(defaultFlagIter->second);
174 10 : flagValues.erase(defaultFlagIter);
175 : }
176 20 : for (const auto &value : flagValues)
177 : {
178 9 : auto currentLevelIter = m_debugLevels.find(componentFromStr(value.first));
179 9 : if (currentLevelIter != m_debugLevels.end())
180 : {
181 8 : currentLevelIter->second = levelFromNumber(value.second);
182 : }
183 : }
184 35 : }
185 :
186 35 : void EnvVariableParser::configureRialtoConsoleLog()
187 : {
188 35 : std::string debugFlagEnvVar = getRialtoConsoleLog();
189 35 : if (debugFlagEnvVar == "1")
190 : {
191 31 : m_logToConsole = true;
192 : }
193 15 : }
194 :
195 35 : void EnvVariableParser::configureFileLogging()
196 : {
197 35 : if (isFileLoggingEnabled())
198 : {
199 1 : LogFileHandle::instance().init(m_logFilePath);
200 : }
201 35 : }
202 :
203 64 : RIALTO_DEBUG_LEVEL EnvVariableParser::getLevel(const RIALTO_COMPONENT &component) const
204 : {
205 64 : if (RIALTO_COMPONENT_EXTERNAL == component)
206 : {
207 8 : return RIALTO_DEBUG_LEVEL_EXTERNAL;
208 : }
209 56 : auto levelIter = m_debugLevels.find(component);
210 56 : if (levelIter == m_debugLevels.end())
211 3 : return RIALTO_DEBUG_LEVEL_DEFAULT;
212 53 : return levelIter->second;
213 : }
214 :
215 9918 : bool EnvVariableParser::isConsoleLoggingEnabled() const
216 : {
217 9918 : return m_logToConsole;
218 : }
219 :
220 9949 : bool EnvVariableParser::isFileLoggingEnabled() const
221 : {
222 9949 : return !m_logFilePath.empty();
223 : }
224 : } // namespace firebolt::rialto::logging
|