ClickHouse
197 строк · 6.0 Кб
1#include "OwnJSONPatternFormatter.h"
2
3#include <functional>
4#include <IO/WriteBufferFromString.h>
5#include <IO/WriteHelpers.h>
6#include <Interpreters/InternalTextLogsQueue.h>
7#include <base/terminalColors.h>
8#include <Common/CurrentThread.h>
9#include <Common/HashTable/Hash.h>
10
11OwnJSONPatternFormatter::OwnJSONPatternFormatter(Poco::Util::AbstractConfiguration & config)
12{
13if (config.has("logger.formatting.names.date_time"))
14date_time = config.getString("logger.formatting.names.date_time", "");
15
16if (config.has("logger.formatting.names.thread_name"))
17thread_name = config.getString("logger.formatting.names.thread_name", "");
18
19if (config.has("logger.formatting.names.thread_id"))
20thread_id = config.getString("logger.formatting.names.thread_id", "");
21
22if (config.has("logger.formatting.names.level"))
23level = config.getString("logger.formatting.names.level", "");
24
25if (config.has("logger.formatting.names.query_id"))
26query_id = config.getString("logger.formatting.names.query_id", "");
27
28if (config.has("logger.formatting.names.logger_name"))
29logger_name = config.getString("logger.formatting.names.logger_name", "");
30
31if (config.has("logger.formatting.names.message"))
32message = config.getString("logger.formatting.names.message", "");
33
34if (config.has("logger.formatting.names.source_file"))
35source_file = config.getString("logger.formatting.names.source_file", "");
36
37if (config.has("logger.formatting.names.source_line"))
38source_line = config.getString("logger.formatting.names.source_line", "");
39
40if (date_time.empty() && thread_name.empty() && thread_id.empty() && level.empty() && query_id.empty()
41&& logger_name.empty() && message.empty() && source_file.empty() && source_line.empty())
42{
43date_time = "date_time";
44thread_name = "thread_name";
45thread_id = "thread_id";
46level = "level";
47query_id = "query_id";
48logger_name = "logger_name";
49message = "message";
50source_file = "source_file";
51source_line = "source_line";
52}
53}
54
55void OwnJSONPatternFormatter::formatExtended(const DB::ExtendedLogMessage & msg_ext, std::string & text) const
56{
57DB::WriteBufferFromString wb(text);
58
59DB::FormatSettings settings;
60bool print_comma = false;
61
62const Poco::Message & msg = msg_ext.base;
63DB::writeChar('{', wb);
64
65if (!date_time.empty())
66{
67writeJSONString(date_time, wb, settings);
68DB::writeChar(':', wb);
69
70DB::writeChar('\"', wb);
71/// Change delimiters in date for compatibility with old logs.
72writeDateTimeUnixTimestamp(msg_ext.time_seconds, 0, wb);
73DB::writeChar('.', wb);
74DB::writeChar('0' + ((msg_ext.time_microseconds / 100000) % 10), wb);
75DB::writeChar('0' + ((msg_ext.time_microseconds / 10000) % 10), wb);
76DB::writeChar('0' + ((msg_ext.time_microseconds / 1000) % 10), wb);
77DB::writeChar('0' + ((msg_ext.time_microseconds / 100) % 10), wb);
78DB::writeChar('0' + ((msg_ext.time_microseconds / 10) % 10), wb);
79DB::writeChar('0' + ((msg_ext.time_microseconds / 1) % 10), wb);
80DB::writeChar('\"', wb);
81print_comma = true;
82}
83
84if (!thread_name.empty())
85{
86if (print_comma)
87DB::writeChar(',', wb);
88else
89print_comma = true;
90
91writeJSONString(thread_name, wb, settings);
92DB::writeChar(':', wb);
93
94writeJSONString(msg.getThread(), wb, settings);
95}
96
97if (!thread_id.empty())
98{
99if (print_comma)
100DB::writeChar(',', wb);
101else
102print_comma = true;
103
104writeJSONString(thread_id, wb, settings);
105DB::writeChar(':', wb);
106DB::writeChar('\"', wb);
107DB::writeIntText(msg_ext.thread_id, wb);
108DB::writeChar('\"', wb);
109}
110
111if (!level.empty())
112{
113if (print_comma)
114DB::writeChar(',', wb);
115else
116print_comma = true;
117
118writeJSONString(level, wb, settings);
119DB::writeChar(':', wb);
120int priority = static_cast<int>(msg.getPriority());
121writeJSONString(getPriorityName(priority), wb, settings);
122}
123
124if (!query_id.empty())
125{
126if (print_comma)
127DB::writeChar(',', wb);
128else
129print_comma = true;
130
131/// We write query_id even in case when it is empty (no query context)
132/// just to be convenient for various log parsers.
133
134writeJSONString(query_id, wb, settings);
135DB::writeChar(':', wb);
136writeJSONString(msg_ext.query_id, wb, settings);
137}
138
139if (!logger_name.empty())
140{
141if (print_comma)
142DB::writeChar(',', wb);
143else
144print_comma = true;
145
146writeJSONString(logger_name, wb, settings);
147DB::writeChar(':', wb);
148
149writeJSONString(msg.getSource(), wb, settings);
150}
151
152if (!message.empty())
153{
154if (print_comma)
155DB::writeChar(',', wb);
156else
157print_comma = true;
158
159writeJSONString(message, wb, settings);
160DB::writeChar(':', wb);
161writeJSONString(msg.getText(), wb, settings);
162}
163
164if (!source_file.empty())
165{
166if (print_comma)
167DB::writeChar(',', wb);
168else
169print_comma = true;
170
171writeJSONString(source_file, wb, settings);
172DB::writeChar(':', wb);
173const char * source_file_name = msg.getSourceFile();
174if (source_file_name != nullptr)
175writeJSONString(source_file_name, wb, settings);
176else
177writeJSONString("", wb, settings);
178}
179
180if (!source_line.empty())
181{
182if (print_comma)
183DB::writeChar(',', wb);
184
185writeJSONString(source_line, wb, settings);
186DB::writeChar(':', wb);
187DB::writeChar('\"', wb);
188DB::writeIntText(msg.getSourceLine(), wb);
189DB::writeChar('\"', wb);
190}
191DB::writeChar('}', wb);
192}
193
194void OwnJSONPatternFormatter::format(const Poco::Message & msg, std::string & text)
195{
196formatExtended(DB::ExtendedLogMessage::getFrom(msg), text);
197}
198