/src/logging-log4cxx/src/main/cpp/patternlayout.cpp
Line | Count | Source |
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 | auto& lsMsg = event->getRenderedMessage(); |
126 | 0 | output.reserve(m_priv->expectedPatternLength + lsMsg.size()); |
127 | 0 | std::vector<FormattingInfoPtr>::const_iterator formatterIter = |
128 | 0 | m_priv->patternFields.begin(); |
129 | |
|
130 | 0 | for (std::vector<LoggingEventPatternConverterPtr>::const_iterator |
131 | 0 | converterIter = m_priv->patternConverters.begin(); |
132 | 0 | converterIter != m_priv->patternConverters.end(); |
133 | 0 | converterIter++, formatterIter++) |
134 | 0 | { |
135 | 0 | int startField = (int)output.length(); |
136 | 0 | (*converterIter)->format(event, output, pool); |
137 | 0 | (*formatterIter)->format(startField, output); |
138 | 0 | } |
139 | |
|
140 | 0 | } |
141 | | |
142 | | void PatternLayout::setOption(const LogString& option, const LogString& value) |
143 | 0 | { |
144 | 0 | if (StringHelper::equalsIgnoreCase(option, |
145 | 0 | LOG4CXX_STR("CONVERSIONPATTERN"), |
146 | 0 | LOG4CXX_STR("conversionpattern"))) |
147 | 0 | { |
148 | 0 | m_priv->conversionPattern = OptionConverter::convertSpecialChars(value); |
149 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
150 | 0 | LOG4CXX_STR("ERRORCOLOR"), |
151 | 0 | LOG4CXX_STR("errorcolor"))){ |
152 | 0 | m_priv->m_errorColor = value; |
153 | 0 | if (LogLog::isDebugEnabled()) |
154 | 0 | { |
155 | 0 | LogString msg(LOG4CXX_STR("Setting error color to ")); |
156 | 0 | msg += value; |
157 | 0 | LogLog::debug(msg); |
158 | 0 | } |
159 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
160 | 0 | LOG4CXX_STR("FATALCOLOR"), |
161 | 0 | LOG4CXX_STR("fatalcolor"))){ |
162 | 0 | m_priv->m_fatalColor = value; |
163 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
164 | 0 | LOG4CXX_STR("WARNCOLOR"), |
165 | 0 | LOG4CXX_STR("warncolor"))){ |
166 | 0 | m_priv->m_warnColor = value; |
167 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
168 | 0 | LOG4CXX_STR("INFOCOLOR"), |
169 | 0 | LOG4CXX_STR("infocolor"))){ |
170 | 0 | m_priv->m_infoColor = value; |
171 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
172 | 0 | LOG4CXX_STR("DEBUGCOLOR"), |
173 | 0 | LOG4CXX_STR("debugcolor"))){ |
174 | 0 | m_priv->m_debugColor = value; |
175 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
176 | 0 | LOG4CXX_STR("TRACECOLOR"), |
177 | 0 | LOG4CXX_STR("tracecolor"))){ |
178 | 0 | m_priv->m_traceColor = value; |
179 | 0 | } |
180 | 0 | } |
181 | | |
182 | | void PatternLayout::activateOptions(Pool&) |
183 | 0 | { |
184 | 0 | LogString pat(m_priv->conversionPattern); |
185 | |
|
186 | 0 | if (pat.empty()) |
187 | 0 | { |
188 | 0 | pat = LOG4CXX_STR("%m%n"); |
189 | 0 | } |
190 | |
|
191 | 0 | m_priv->patternConverters.erase(m_priv->patternConverters.begin(), m_priv->patternConverters.end()); |
192 | 0 | m_priv->patternFields.erase(m_priv->patternFields.begin(), m_priv->patternFields.end()); |
193 | 0 | std::vector<PatternConverterPtr> converters; |
194 | 0 | PatternParser::parse(pat, |
195 | 0 | converters, |
196 | 0 | m_priv->patternFields, |
197 | 0 | getFormatSpecifiers()); |
198 | | |
199 | | // |
200 | | // strip out any pattern converters that don't handle LoggingEvents |
201 | | // |
202 | | // |
203 | 0 | for (auto const& converterItem : converters) |
204 | 0 | { |
205 | 0 | if (auto eventConverter = LOG4CXX_NS::cast<LoggingEventPatternConverter>(converterItem)) |
206 | 0 | { |
207 | 0 | m_priv->patternConverters.push_back(eventConverter); |
208 | 0 | } |
209 | 0 | } |
210 | 0 | m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2; |
211 | 0 | } |
212 | | |
213 | | #define RULES_PUT(spec, cls) \ |
214 | 0 | specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), cls ::newInstance)) |
215 | | |
216 | | |
217 | | LOG4CXX_NS::pattern::PatternMap PatternLayout::getFormatSpecifiers() |
218 | 0 | { |
219 | 0 | PatternMap specs; |
220 | 0 | RULES_PUT("c", LoggerPatternConverter); |
221 | 0 | RULES_PUT("logger", LoggerPatternConverter); |
222 | |
|
223 | 0 | RULES_PUT("C", ClassNamePatternConverter); |
224 | 0 | RULES_PUT("class", ClassNamePatternConverter); |
225 | |
|
226 | 0 | specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR("Y")), std::bind(&PatternLayout::createColorStartPatternConverter, this, std::placeholders::_1))); |
227 | 0 | RULES_PUT("y", ColorEndPatternConverter); |
228 | |
|
229 | 0 | RULES_PUT("d", DatePatternConverter); |
230 | 0 | RULES_PUT("date", DatePatternConverter); |
231 | |
|
232 | 0 | RULES_PUT("f", ShortFileLocationPatternConverter); |
233 | |
|
234 | 0 | RULES_PUT("F", FileLocationPatternConverter); |
235 | 0 | RULES_PUT("file", FileLocationPatternConverter); |
236 | |
|
237 | 0 | RULES_PUT("l", FullLocationPatternConverter); |
238 | |
|
239 | 0 | RULES_PUT("L", LineLocationPatternConverter); |
240 | 0 | RULES_PUT("line", LineLocationPatternConverter); |
241 | |
|
242 | 0 | RULES_PUT("m", MessagePatternConverter); |
243 | 0 | RULES_PUT("message", MessagePatternConverter); |
244 | |
|
245 | 0 | RULES_PUT("n", LineSeparatorPatternConverter); |
246 | |
|
247 | 0 | RULES_PUT("M", MethodLocationPatternConverter); |
248 | 0 | RULES_PUT("method", MethodLocationPatternConverter); |
249 | |
|
250 | 0 | RULES_PUT("p", LevelPatternConverter); |
251 | 0 | RULES_PUT("level", LevelPatternConverter); |
252 | |
|
253 | 0 | RULES_PUT("r", RelativeTimePatternConverter); |
254 | 0 | RULES_PUT("relative", RelativeTimePatternConverter); |
255 | |
|
256 | 0 | RULES_PUT("t", ThreadPatternConverter); |
257 | 0 | RULES_PUT("thread", ThreadPatternConverter); |
258 | |
|
259 | 0 | RULES_PUT("T", ThreadUsernamePatternConverter); |
260 | 0 | RULES_PUT("threadname", ThreadUsernamePatternConverter); |
261 | |
|
262 | 0 | RULES_PUT("x", NDCPatternConverter); |
263 | 0 | RULES_PUT("ndc", NDCPatternConverter); |
264 | |
|
265 | 0 | RULES_PUT("X", PropertiesPatternConverter); |
266 | 0 | RULES_PUT("J", MDCPatternConverter); |
267 | 0 | RULES_PUT("properties", PropertiesPatternConverter); |
268 | |
|
269 | 0 | RULES_PUT("throwable", ThrowableInformationPatternConverter); |
270 | 0 | return specs; |
271 | 0 | } |
272 | | |
273 | | LogString PatternLayout::getConversionPattern() const |
274 | 0 | { |
275 | 0 | return m_priv->conversionPattern; |
276 | 0 | } |
277 | | |
278 | 0 | pattern::PatternConverterPtr PatternLayout::createColorStartPatternConverter(const std::vector<LogString>& options){ |
279 | 0 | std::shared_ptr<ColorStartPatternConverter> colorPatternConverter = std::make_shared<ColorStartPatternConverter>(); |
280 | |
|
281 | 0 | colorPatternConverter->setErrorColor(m_priv->m_errorColor); |
282 | 0 | colorPatternConverter->setFatalColor(m_priv->m_fatalColor); |
283 | 0 | colorPatternConverter->setWarnColor(m_priv->m_warnColor); |
284 | 0 | colorPatternConverter->setInfoColor(m_priv->m_infoColor); |
285 | 0 | colorPatternConverter->setDebugColor(m_priv->m_debugColor); |
286 | 0 | colorPatternConverter->setTraceColor(m_priv->m_traceColor); |
287 | |
|
288 | 0 | return colorPatternConverter; |
289 | 0 | } |
290 | | |
291 | | |
292 | | |