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