/src/logging-log4cxx/src/main/cpp/patternlayout.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | * contributor license agreements. See the NOTICE file distributed with |
4 | | * this work for additional information regarding copyright ownership. |
5 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | | * (the "License"); you may not use this file except in compliance with |
7 | | * the License. You may obtain a copy of the License at |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | |
18 | | #include <log4cxx/logstring.h> |
19 | | #include <log4cxx/patternlayout.h> |
20 | | #include <log4cxx/pattern/patternparser.h> |
21 | | #include <log4cxx/pattern/loggingeventpatternconverter.h> |
22 | | #include <log4cxx/pattern/formattinginfo.h> |
23 | | #include <log4cxx/helpers/stringhelper.h> |
24 | | #include <log4cxx/helpers/pool.h> |
25 | | #include <log4cxx/helpers/optionconverter.h> |
26 | | |
27 | | #include <log4cxx/pattern/loggerpatternconverter.h> |
28 | | #include <log4cxx/pattern/colorendpatternconverter.h> |
29 | | #include <log4cxx/pattern/colorstartpatternconverter.h> |
30 | | #include <log4cxx/pattern/shortfilelocationpatternconverter.h> |
31 | | #include <log4cxx/pattern/literalpatternconverter.h> |
32 | | #include <log4cxx/helpers/loglog.h> |
33 | | #include <log4cxx/pattern/classnamepatternconverter.h> |
34 | | #include <log4cxx/pattern/datepatternconverter.h> |
35 | | #include <log4cxx/pattern/filedatepatternconverter.h> |
36 | | #include <log4cxx/pattern/filelocationpatternconverter.h> |
37 | | #include <log4cxx/pattern/fulllocationpatternconverter.h> |
38 | | #include <log4cxx/pattern/integerpatternconverter.h> |
39 | | #include <log4cxx/pattern/linelocationpatternconverter.h> |
40 | | #include <log4cxx/pattern/messagepatternconverter.h> |
41 | | #include <log4cxx/pattern/lineseparatorpatternconverter.h> |
42 | | #include <log4cxx/pattern/methodlocationpatternconverter.h> |
43 | | #include <log4cxx/pattern/levelpatternconverter.h> |
44 | | #include <log4cxx/pattern/relativetimepatternconverter.h> |
45 | | #include <log4cxx/pattern/threadpatternconverter.h> |
46 | | #include <log4cxx/pattern/mdcpatternconverter.h> |
47 | | #include <log4cxx/pattern/ndcpatternconverter.h> |
48 | | #include <log4cxx/pattern/propertiespatternconverter.h> |
49 | | #include <log4cxx/pattern/throwableinformationpatternconverter.h> |
50 | | #include <log4cxx/pattern/threadusernamepatternconverter.h> |
51 | | |
52 | | |
53 | | using namespace LOG4CXX_NS; |
54 | | using namespace LOG4CXX_NS::helpers; |
55 | | using namespace LOG4CXX_NS::spi; |
56 | | using namespace LOG4CXX_NS::pattern; |
57 | | |
58 | | struct PatternLayout::PatternLayoutPrivate |
59 | | { |
60 | | PatternLayoutPrivate() |
61 | 0 | : expectedPatternLength(100) |
62 | 0 | {} |
63 | | PatternLayoutPrivate(const LogString& pattern) |
64 | 0 | : conversionPattern(pattern) |
65 | 0 | , expectedPatternLength(100) |
66 | 0 | {} |
67 | | |
68 | | /** |
69 | | * Conversion pattern. |
70 | | */ |
71 | | LogString conversionPattern; |
72 | | |
73 | | /** |
74 | | * Pattern converters. |
75 | | */ |
76 | | LoggingEventPatternConverterList patternConverters; |
77 | | |
78 | | /** |
79 | | * Field widths and alignment corresponding to pattern converters. |
80 | | */ |
81 | | FormattingInfoList patternFields; |
82 | | |
83 | | LogString m_fatalColor = LOG4CXX_STR("\\x1B[35m"); //magenta |
84 | | LogString m_errorColor = LOG4CXX_STR("\\x1B[31m"); //red |
85 | | LogString m_warnColor = LOG4CXX_STR("\\x1B[33m"); //yellow |
86 | | LogString m_infoColor = LOG4CXX_STR("\\x1B[32m"); //green |
87 | | LogString m_debugColor = LOG4CXX_STR("\\x1B[36m"); //cyan; |
88 | | LogString m_traceColor = LOG4CXX_STR("\\x1B[34m"); //blue; |
89 | | |
90 | | // Expected length of a formatted event excluding the message text |
91 | | size_t expectedPatternLength; |
92 | | }; |
93 | | |
94 | | IMPLEMENT_LOG4CXX_OBJECT(PatternLayout) |
95 | | |
96 | | |
97 | | PatternLayout::PatternLayout() : |
98 | 0 | m_priv(std::make_unique<PatternLayoutPrivate>()) |
99 | 0 | { |
100 | 0 | } Unexecuted instantiation: log4cxx::PatternLayout::PatternLayout() Unexecuted instantiation: log4cxx::PatternLayout::PatternLayout() |
101 | | |
102 | | /** |
103 | | Constructs a PatternLayout using the supplied conversion pattern. |
104 | | */ |
105 | | PatternLayout::PatternLayout(const LogString& pattern) : |
106 | 0 | m_priv(std::make_unique<PatternLayoutPrivate>(pattern)) |
107 | 0 | { |
108 | 0 | Pool pool; |
109 | 0 | activateOptions(pool); |
110 | 0 | } Unexecuted instantiation: log4cxx::PatternLayout::PatternLayout(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&) Unexecuted instantiation: log4cxx::PatternLayout::PatternLayout(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&) |
111 | | |
112 | 0 | PatternLayout::~PatternLayout() {} |
113 | | |
114 | | void PatternLayout::setConversionPattern(const LogString& pattern) |
115 | 0 | { |
116 | 0 | m_priv->conversionPattern = pattern; |
117 | 0 | Pool pool; |
118 | 0 | activateOptions(pool); |
119 | 0 | } |
120 | | |
121 | | void PatternLayout::format(LogString& output, |
122 | | const spi::LoggingEventPtr& event, |
123 | | Pool& pool) const |
124 | 0 | { |
125 | 0 | output.reserve(m_priv->expectedPatternLength + event->getMessage().size()); |
126 | 0 | std::vector<FormattingInfoPtr>::const_iterator formatterIter = |
127 | 0 | m_priv->patternFields.begin(); |
128 | |
|
129 | 0 | for (std::vector<LoggingEventPatternConverterPtr>::const_iterator |
130 | 0 | converterIter = m_priv->patternConverters.begin(); |
131 | 0 | converterIter != m_priv->patternConverters.end(); |
132 | 0 | converterIter++, formatterIter++) |
133 | 0 | { |
134 | 0 | int startField = (int)output.length(); |
135 | 0 | (*converterIter)->format(event, output, pool); |
136 | 0 | (*formatterIter)->format(startField, output); |
137 | 0 | } |
138 | |
|
139 | 0 | } |
140 | | |
141 | | void PatternLayout::setOption(const LogString& option, const LogString& value) |
142 | 0 | { |
143 | 0 | if (StringHelper::equalsIgnoreCase(option, |
144 | 0 | LOG4CXX_STR("CONVERSIONPATTERN"), |
145 | 0 | LOG4CXX_STR("conversionpattern"))) |
146 | 0 | { |
147 | 0 | m_priv->conversionPattern = OptionConverter::convertSpecialChars(value); |
148 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
149 | 0 | LOG4CXX_STR("ERRORCOLOR"), |
150 | 0 | LOG4CXX_STR("errorcolor"))){ |
151 | 0 | m_priv->m_errorColor = value; |
152 | 0 | if (LogLog::isDebugEnabled()) |
153 | 0 | { |
154 | 0 | LogString msg(LOG4CXX_STR("Setting error color to ")); |
155 | 0 | msg += value; |
156 | 0 | LogLog::debug(msg); |
157 | 0 | } |
158 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
159 | 0 | LOG4CXX_STR("FATALCOLOR"), |
160 | 0 | LOG4CXX_STR("fatalcolor"))){ |
161 | 0 | m_priv->m_fatalColor = value; |
162 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
163 | 0 | LOG4CXX_STR("WARNCOLOR"), |
164 | 0 | LOG4CXX_STR("warncolor"))){ |
165 | 0 | m_priv->m_warnColor = value; |
166 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
167 | 0 | LOG4CXX_STR("INFOCOLOR"), |
168 | 0 | LOG4CXX_STR("infocolor"))){ |
169 | 0 | m_priv->m_infoColor = value; |
170 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
171 | 0 | LOG4CXX_STR("DEBUGCOLOR"), |
172 | 0 | LOG4CXX_STR("debugcolor"))){ |
173 | 0 | m_priv->m_debugColor = value; |
174 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
175 | 0 | LOG4CXX_STR("TRACECOLOR"), |
176 | 0 | LOG4CXX_STR("tracecolor"))){ |
177 | 0 | m_priv->m_traceColor = value; |
178 | 0 | } |
179 | 0 | } |
180 | | |
181 | | void PatternLayout::activateOptions(Pool&) |
182 | 0 | { |
183 | 0 | LogString pat(m_priv->conversionPattern); |
184 | |
|
185 | 0 | if (pat.empty()) |
186 | 0 | { |
187 | 0 | pat = LOG4CXX_STR("%m%n"); |
188 | 0 | } |
189 | |
|
190 | 0 | m_priv->patternConverters.erase(m_priv->patternConverters.begin(), m_priv->patternConverters.end()); |
191 | 0 | m_priv->patternFields.erase(m_priv->patternFields.begin(), m_priv->patternFields.end()); |
192 | 0 | std::vector<PatternConverterPtr> converters; |
193 | 0 | PatternParser::parse(pat, |
194 | 0 | converters, |
195 | 0 | m_priv->patternFields, |
196 | 0 | getFormatSpecifiers()); |
197 | | |
198 | | // |
199 | | // strip out any pattern converters that don't handle LoggingEvents |
200 | | // |
201 | | // |
202 | 0 | for (auto const& converterItem : converters) |
203 | 0 | { |
204 | 0 | if (auto eventConverter = LOG4CXX_NS::cast<LoggingEventPatternConverter>(converterItem)) |
205 | 0 | { |
206 | 0 | m_priv->patternConverters.push_back(eventConverter); |
207 | 0 | } |
208 | 0 | } |
209 | 0 | m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2; |
210 | 0 | } |
211 | | |
212 | | #define RULES_PUT(spec, cls) \ |
213 | 0 | specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), cls ::newInstance)) |
214 | | |
215 | | |
216 | | LOG4CXX_NS::pattern::PatternMap PatternLayout::getFormatSpecifiers() |
217 | 0 | { |
218 | 0 | PatternMap specs; |
219 | 0 | RULES_PUT("c", LoggerPatternConverter); |
220 | 0 | RULES_PUT("logger", LoggerPatternConverter); |
221 | |
|
222 | 0 | RULES_PUT("C", ClassNamePatternConverter); |
223 | 0 | RULES_PUT("class", ClassNamePatternConverter); |
224 | |
|
225 | 0 | specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR("Y")), std::bind(&PatternLayout::createColorStartPatternConverter, this, std::placeholders::_1))); |
226 | 0 | RULES_PUT("y", ColorEndPatternConverter); |
227 | |
|
228 | 0 | RULES_PUT("d", DatePatternConverter); |
229 | 0 | RULES_PUT("date", DatePatternConverter); |
230 | |
|
231 | 0 | RULES_PUT("f", ShortFileLocationPatternConverter); |
232 | |
|
233 | 0 | RULES_PUT("F", FileLocationPatternConverter); |
234 | 0 | RULES_PUT("file", FileLocationPatternConverter); |
235 | |
|
236 | 0 | RULES_PUT("l", FullLocationPatternConverter); |
237 | |
|
238 | 0 | RULES_PUT("L", LineLocationPatternConverter); |
239 | 0 | RULES_PUT("line", LineLocationPatternConverter); |
240 | |
|
241 | 0 | RULES_PUT("m", MessagePatternConverter); |
242 | 0 | RULES_PUT("message", MessagePatternConverter); |
243 | |
|
244 | 0 | RULES_PUT("n", LineSeparatorPatternConverter); |
245 | |
|
246 | 0 | RULES_PUT("M", MethodLocationPatternConverter); |
247 | 0 | RULES_PUT("method", MethodLocationPatternConverter); |
248 | |
|
249 | 0 | RULES_PUT("p", LevelPatternConverter); |
250 | 0 | RULES_PUT("level", LevelPatternConverter); |
251 | |
|
252 | 0 | RULES_PUT("r", RelativeTimePatternConverter); |
253 | 0 | RULES_PUT("relative", RelativeTimePatternConverter); |
254 | |
|
255 | 0 | RULES_PUT("t", ThreadPatternConverter); |
256 | 0 | RULES_PUT("thread", ThreadPatternConverter); |
257 | |
|
258 | 0 | RULES_PUT("T", ThreadUsernamePatternConverter); |
259 | 0 | RULES_PUT("threadname", ThreadUsernamePatternConverter); |
260 | |
|
261 | 0 | RULES_PUT("x", NDCPatternConverter); |
262 | 0 | RULES_PUT("ndc", NDCPatternConverter); |
263 | |
|
264 | 0 | RULES_PUT("X", PropertiesPatternConverter); |
265 | 0 | RULES_PUT("J", MDCPatternConverter); |
266 | 0 | RULES_PUT("properties", PropertiesPatternConverter); |
267 | |
|
268 | 0 | RULES_PUT("throwable", ThrowableInformationPatternConverter); |
269 | 0 | return specs; |
270 | 0 | } |
271 | | |
272 | | LogString PatternLayout::getConversionPattern() const |
273 | 0 | { |
274 | 0 | return m_priv->conversionPattern; |
275 | 0 | } |
276 | | |
277 | 0 | pattern::PatternConverterPtr PatternLayout::createColorStartPatternConverter(const std::vector<LogString>& options){ |
278 | 0 | std::shared_ptr<ColorStartPatternConverter> colorPatternConverter = std::make_shared<ColorStartPatternConverter>(); |
279 | |
|
280 | 0 | colorPatternConverter->setErrorColor(m_priv->m_errorColor); |
281 | 0 | colorPatternConverter->setFatalColor(m_priv->m_fatalColor); |
282 | 0 | colorPatternConverter->setWarnColor(m_priv->m_warnColor); |
283 | 0 | colorPatternConverter->setInfoColor(m_priv->m_infoColor); |
284 | 0 | colorPatternConverter->setDebugColor(m_priv->m_debugColor); |
285 | 0 | colorPatternConverter->setTraceColor(m_priv->m_traceColor); |
286 | |
|
287 | 0 | return colorPatternConverter; |
288 | 0 | } |
289 | | |
290 | | |
291 | | |