/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 | | LogString m_fatalColor = LOG4CXX_STR("\\x1B[35m"); //magenta |
79 | | LogString m_errorColor = LOG4CXX_STR("\\x1B[31m"); //red |
80 | | LogString m_warnColor = LOG4CXX_STR("\\x1B[33m"); //yellow |
81 | | LogString m_infoColor = LOG4CXX_STR("\\x1B[32m"); //green |
82 | | LogString m_debugColor = LOG4CXX_STR("\\x1B[36m"); //cyan; |
83 | | LogString m_traceColor = LOG4CXX_STR("\\x1B[34m"); //blue; |
84 | | |
85 | | // Expected length of a formatted event excluding the message text |
86 | | size_t expectedPatternLength; |
87 | | }; |
88 | | |
89 | | IMPLEMENT_LOG4CXX_OBJECT(PatternLayout) |
90 | | |
91 | | |
92 | | PatternLayout::PatternLayout() : |
93 | 0 | m_priv(std::make_unique<PatternLayoutPrivate>()) |
94 | 0 | { |
95 | 0 | } Unexecuted instantiation: log4cxx::PatternLayout::PatternLayout() Unexecuted instantiation: log4cxx::PatternLayout::PatternLayout() |
96 | | |
97 | | /** |
98 | | Constructs a PatternLayout using the supplied conversion pattern. |
99 | | */ |
100 | | PatternLayout::PatternLayout(const LogString& pattern) : |
101 | 0 | m_priv(std::make_unique<PatternLayoutPrivate>(pattern)) |
102 | 0 | { |
103 | 0 | Pool pool; |
104 | 0 | activateOptions(pool); |
105 | 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&) |
106 | | |
107 | 0 | PatternLayout::~PatternLayout() {} |
108 | | |
109 | | void PatternLayout::setConversionPattern(const LogString& pattern) |
110 | 0 | { |
111 | 0 | m_priv->conversionPattern = pattern; |
112 | 0 | Pool pool; |
113 | 0 | activateOptions(pool); |
114 | 0 | } |
115 | | |
116 | | void PatternLayout::format(LogString& output, |
117 | | const spi::LoggingEventPtr& event, |
118 | | Pool& pool) const |
119 | 0 | { |
120 | 0 | auto& lsMsg = event->getRenderedMessage(); |
121 | 0 | output.reserve(m_priv->expectedPatternLength + lsMsg.size()); |
122 | |
|
123 | 0 | for (auto item : m_priv->patternConverters) |
124 | 0 | { |
125 | 0 | auto startField = output.length(); |
126 | 0 | item->format(event, output, pool); |
127 | 0 | if (startField < INT_MAX) |
128 | 0 | item->getFormattingInfo().format(static_cast<int>(startField), output); |
129 | 0 | } |
130 | |
|
131 | 0 | } |
132 | | |
133 | | void PatternLayout::setOption(const LogString& option, const LogString& value) |
134 | 0 | { |
135 | 0 | if (StringHelper::equalsIgnoreCase(option, |
136 | 0 | LOG4CXX_STR("CONVERSIONPATTERN"), |
137 | 0 | LOG4CXX_STR("conversionpattern"))) |
138 | 0 | { |
139 | 0 | m_priv->conversionPattern = OptionConverter::convertSpecialChars(value); |
140 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
141 | 0 | LOG4CXX_STR("ERRORCOLOR"), |
142 | 0 | LOG4CXX_STR("errorcolor"))){ |
143 | 0 | m_priv->m_errorColor = value; |
144 | 0 | if (LogLog::isDebugEnabled()) |
145 | 0 | { |
146 | 0 | LogString msg(LOG4CXX_STR("Setting error color to ")); |
147 | 0 | msg += value; |
148 | 0 | LogLog::debug(msg); |
149 | 0 | } |
150 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
151 | 0 | LOG4CXX_STR("FATALCOLOR"), |
152 | 0 | LOG4CXX_STR("fatalcolor"))){ |
153 | 0 | m_priv->m_fatalColor = value; |
154 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
155 | 0 | LOG4CXX_STR("WARNCOLOR"), |
156 | 0 | LOG4CXX_STR("warncolor"))){ |
157 | 0 | m_priv->m_warnColor = value; |
158 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
159 | 0 | LOG4CXX_STR("INFOCOLOR"), |
160 | 0 | LOG4CXX_STR("infocolor"))){ |
161 | 0 | m_priv->m_infoColor = value; |
162 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
163 | 0 | LOG4CXX_STR("DEBUGCOLOR"), |
164 | 0 | LOG4CXX_STR("debugcolor"))){ |
165 | 0 | m_priv->m_debugColor = value; |
166 | 0 | }else if(StringHelper::equalsIgnoreCase(option, |
167 | 0 | LOG4CXX_STR("TRACECOLOR"), |
168 | 0 | LOG4CXX_STR("tracecolor"))){ |
169 | 0 | m_priv->m_traceColor = value; |
170 | 0 | } |
171 | 0 | } |
172 | | |
173 | | void PatternLayout::activateOptions(Pool&) |
174 | 0 | { |
175 | 0 | LogString pat(m_priv->conversionPattern); |
176 | |
|
177 | 0 | if (pat.empty()) |
178 | 0 | { |
179 | 0 | pat = LOG4CXX_STR("%m%n"); |
180 | 0 | } |
181 | |
|
182 | 0 | m_priv->patternConverters.erase(m_priv->patternConverters.begin(), m_priv->patternConverters.end()); |
183 | 0 | auto converters = PatternParser::parse(pat, getFormatSpecifiers()); |
184 | | |
185 | | // |
186 | | // strip out any pattern converters that don't handle LoggingEvents |
187 | | // |
188 | | // |
189 | 0 | for (auto const& converterItem : converters) |
190 | 0 | { |
191 | 0 | if (auto eventConverter = LOG4CXX_NS::cast<LoggingEventPatternConverter>(converterItem)) |
192 | 0 | { |
193 | 0 | m_priv->patternConverters.push_back(eventConverter); |
194 | 0 | } |
195 | 0 | } |
196 | 0 | m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2; |
197 | 0 | } |
198 | | |
199 | | #define RULES_PUT(spec, cls) \ |
200 | 0 | specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), cls ::newInstance)) |
201 | | |
202 | | |
203 | | LOG4CXX_NS::pattern::PatternMap PatternLayout::getFormatSpecifiers() |
204 | 0 | { |
205 | 0 | PatternMap specs; |
206 | 0 | RULES_PUT("c", LoggerPatternConverter); |
207 | 0 | RULES_PUT("logger", LoggerPatternConverter); |
208 | |
|
209 | 0 | RULES_PUT("C", ClassNamePatternConverter); |
210 | 0 | RULES_PUT("class", ClassNamePatternConverter); |
211 | |
|
212 | 0 | specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR("Y")), std::bind(&PatternLayout::createColorStartPatternConverter, this, std::placeholders::_1))); |
213 | 0 | RULES_PUT("y", ColorEndPatternConverter); |
214 | |
|
215 | 0 | RULES_PUT("d", DatePatternConverter); |
216 | 0 | RULES_PUT("date", DatePatternConverter); |
217 | |
|
218 | 0 | RULES_PUT("f", ShortFileLocationPatternConverter); |
219 | |
|
220 | 0 | RULES_PUT("F", FileLocationPatternConverter); |
221 | 0 | RULES_PUT("file", FileLocationPatternConverter); |
222 | |
|
223 | 0 | RULES_PUT("l", FullLocationPatternConverter); |
224 | |
|
225 | 0 | RULES_PUT("L", LineLocationPatternConverter); |
226 | 0 | RULES_PUT("line", LineLocationPatternConverter); |
227 | |
|
228 | 0 | RULES_PUT("m", MessagePatternConverter); |
229 | 0 | RULES_PUT("message", MessagePatternConverter); |
230 | |
|
231 | 0 | RULES_PUT("n", LineSeparatorPatternConverter); |
232 | |
|
233 | 0 | RULES_PUT("M", MethodLocationPatternConverter); |
234 | 0 | RULES_PUT("method", MethodLocationPatternConverter); |
235 | |
|
236 | 0 | RULES_PUT("p", LevelPatternConverter); |
237 | 0 | RULES_PUT("level", LevelPatternConverter); |
238 | |
|
239 | 0 | RULES_PUT("r", RelativeTimePatternConverter); |
240 | 0 | RULES_PUT("relative", RelativeTimePatternConverter); |
241 | |
|
242 | 0 | RULES_PUT("t", ThreadPatternConverter); |
243 | 0 | RULES_PUT("thread", ThreadPatternConverter); |
244 | |
|
245 | 0 | RULES_PUT("T", ThreadUsernamePatternConverter); |
246 | 0 | RULES_PUT("threadname", ThreadUsernamePatternConverter); |
247 | |
|
248 | 0 | RULES_PUT("x", NDCPatternConverter); |
249 | 0 | RULES_PUT("ndc", NDCPatternConverter); |
250 | |
|
251 | 0 | RULES_PUT("X", PropertiesPatternConverter); |
252 | 0 | RULES_PUT("J", MDCPatternConverter); |
253 | 0 | RULES_PUT("properties", PropertiesPatternConverter); |
254 | |
|
255 | 0 | RULES_PUT("throwable", ThrowableInformationPatternConverter); |
256 | 0 | return specs; |
257 | 0 | } |
258 | | |
259 | | LogString PatternLayout::getConversionPattern() const |
260 | 0 | { |
261 | 0 | return m_priv->conversionPattern; |
262 | 0 | } |
263 | | |
264 | 0 | pattern::PatternConverterPtr PatternLayout::createColorStartPatternConverter(const std::vector<LogString>& options){ |
265 | 0 | std::shared_ptr<ColorStartPatternConverter> colorPatternConverter = std::make_shared<ColorStartPatternConverter>(); |
266 | |
|
267 | 0 | colorPatternConverter->setErrorColor(m_priv->m_errorColor); |
268 | 0 | colorPatternConverter->setFatalColor(m_priv->m_fatalColor); |
269 | 0 | colorPatternConverter->setWarnColor(m_priv->m_warnColor); |
270 | 0 | colorPatternConverter->setInfoColor(m_priv->m_infoColor); |
271 | 0 | colorPatternConverter->setDebugColor(m_priv->m_debugColor); |
272 | 0 | colorPatternConverter->setTraceColor(m_priv->m_traceColor); |
273 | |
|
274 | 0 | return colorPatternConverter; |
275 | 0 | } |
276 | | |
277 | | |
278 | | |