Coverage Report

Created: 2025-10-13 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/cpp/htmllayout.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/htmllayout.h>
20
#include <log4cxx/spi/loggingevent.h>
21
#include <log4cxx/helpers/optionconverter.h>
22
#include <log4cxx/level.h>
23
#include <log4cxx/helpers/transform.h>
24
#include <log4cxx/helpers/iso8601dateformat.h>
25
#include <log4cxx/helpers/stringhelper.h>
26
#include <log4cxx/helpers/transcoder.h>
27
#include <log4cxx/helpers/date.h>
28
29
using namespace LOG4CXX_NS;
30
using namespace LOG4CXX_NS::helpers;
31
using namespace LOG4CXX_NS::spi;
32
33
struct HTMLLayout::HTMLLayoutPrivate
34
{
35
  HTMLLayoutPrivate()
36
0
    : locationInfo(false)
37
0
    , title(LOG4CXX_STR("Log4cxx Log Messages"))
38
0
    , dateFormat()
39
0
    , expectedPatternLength(100)
40
0
    {}
41
42
  // Print no location info by default
43
  bool locationInfo; //= false
44
45
  LogString title;
46
47
  helpers::ISO8601DateFormat dateFormat;
48
49
  // Expected length of a formatted event excluding the message text
50
  size_t expectedPatternLength;
51
};
52
53
IMPLEMENT_LOG4CXX_OBJECT(HTMLLayout)
54
55
56
HTMLLayout::HTMLLayout()
57
0
  : m_priv(std::make_unique<HTMLLayoutPrivate>())
58
0
{
59
0
  m_priv->dateFormat.setTimeZone(TimeZone::getGMT());
60
0
  m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
61
0
}
Unexecuted instantiation: log4cxx::HTMLLayout::HTMLLayout()
Unexecuted instantiation: log4cxx::HTMLLayout::HTMLLayout()
62
63
0
HTMLLayout::~HTMLLayout() {}
64
65
66
void HTMLLayout::setOption(const LogString& option,
67
  const LogString& value)
68
0
{
69
70
0
  if (StringHelper::equalsIgnoreCase(option,
71
0
      LOG4CXX_STR("TITLE"), LOG4CXX_STR("title")))
72
0
  {
73
0
    setTitle(value);
74
0
  }
75
0
  else if (StringHelper::equalsIgnoreCase(option,
76
0
      LOG4CXX_STR("LOCATIONINFO"), LOG4CXX_STR("locationinfo")))
77
0
  {
78
0
    setLocationInfo(OptionConverter::toBoolean(value, false));
79
0
    m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
80
0
  }
81
0
}
82
83
void HTMLLayout::format(LogString& output,
84
  const spi::LoggingEventPtr& event,
85
  Pool& p) const
86
0
{
87
0
  auto& lsMsg = event->getRenderedMessage();
88
0
  output.reserve(m_priv->expectedPatternLength + lsMsg.size());
89
0
  output.append(LOG4CXX_EOL);
90
0
  output.append(LOG4CXX_STR("<tr>"));
91
0
  output.append(LOG4CXX_EOL);
92
0
  output.append(LOG4CXX_STR("<td>"));
93
94
0
  m_priv->dateFormat.format(output, event->getTimeStamp(), p);
95
96
97
0
  output.append(LOG4CXX_STR("</td>"));
98
0
  output.append(LOG4CXX_EOL);
99
100
0
  output.append(LOG4CXX_STR("<td title=\""));
101
0
  LogString threadName(event->getThreadName());
102
0
  Transform::appendEscapingTags(output, threadName);
103
0
  output.append(LOG4CXX_STR(" thread\">"));
104
0
  Transform::appendEscapingTags(output, threadName);
105
0
  output.append(LOG4CXX_STR("</td>"));
106
0
  output.append(LOG4CXX_EOL);
107
108
0
  output.append(LOG4CXX_STR("<td title=\"Level\">"));
109
110
0
  if (event->getLevel()->equals(Level::getDebug()))
111
0
  {
112
0
    output.append(LOG4CXX_STR("<font color=\"#339933\">"));
113
0
    Transform::appendEscapingTags(output, event->getLevel()->toString());
114
0
    output.append(LOG4CXX_STR("</font>"));
115
0
  }
116
0
  else if (event->getLevel()->isGreaterOrEqual(Level::getWarn()))
117
0
  {
118
0
    output.append(LOG4CXX_STR("<font color=\"#993300\"><strong>"));
119
0
    Transform::appendEscapingTags(output, event->getLevel()->toString());
120
0
    output.append(LOG4CXX_STR("</strong></font>"));
121
0
  }
122
0
  else
123
0
  {
124
0
    Transform::appendEscapingTags(output, event->getLevel()->toString());
125
0
  }
126
127
0
  output.append(LOG4CXX_STR("</td>"));
128
0
  output.append(LOG4CXX_EOL);
129
130
0
  output.append(LOG4CXX_STR("<td title=\""));
131
0
  Transform::appendEscapingTags(output, event->getLoggerName());
132
0
  output.append(LOG4CXX_STR(" logger\">"));
133
0
  Transform::appendEscapingTags(output, event->getLoggerName());
134
0
  output.append(LOG4CXX_STR("</td>"));
135
0
  output.append(LOG4CXX_EOL);
136
137
0
  if (m_priv->locationInfo)
138
0
  {
139
0
    output.append(LOG4CXX_STR("<td>"));
140
0
    const LocationInfo& locInfo = event->getLocationInformation();
141
0
    LOG4CXX_DECODE_CHAR(fileName, locInfo.getFileName());
142
0
    Transform::appendEscapingTags(output, fileName);
143
0
    output.append(1, (logchar) 0x3A /* ':' */);
144
0
    int line = event->getLocationInformation().getLineNumber();
145
146
0
    if (line != 0)
147
0
    {
148
0
      StringHelper::toString(line, p, output);
149
0
    }
150
151
0
    output.append(LOG4CXX_STR("</td>"));
152
0
    output.append(LOG4CXX_EOL);
153
0
  }
154
155
0
  output.append(LOG4CXX_STR("<td title=\"Message\">"));
156
0
  Transform::appendEscapingTags(output, lsMsg);
157
0
  output.append(LOG4CXX_STR("</td>"));
158
0
  output.append(LOG4CXX_EOL);
159
0
  output.append(LOG4CXX_STR("</tr>"));
160
0
  output.append(LOG4CXX_EOL);
161
162
0
  LogString ndcVal;
163
164
0
  if (event->getNDC(ndcVal))
165
0
  {
166
0
    output.append(LOG4CXX_STR("<tr><td bgcolor=\"#EEEEEE\" "));
167
0
    output.append(LOG4CXX_STR("style=\"font-size : xx-small;\" colspan=\"6\" "));
168
0
    output.append(LOG4CXX_STR("title=\"Nested Diagnostic Context\">"));
169
0
    output.append(LOG4CXX_STR("NDC: "));
170
0
    Transform::appendEscapingTags(output, ndcVal);
171
0
    output.append(LOG4CXX_STR("</td></tr>"));
172
0
    output.append(LOG4CXX_EOL);
173
0
  }
174
0
}
175
176
void HTMLLayout::appendHeader(LogString& output, Pool& p)
177
0
{
178
0
  output.append(LOG4CXX_STR("<!DOCTYPE HTML PUBLIC "));
179
0
  output.append(LOG4CXX_STR("\"-//W3C//DTD HTML 4.01 Transitional//EN\" "));
180
0
  output.append(LOG4CXX_STR("\"http://www.w3.org/TR/html4/loose.dtd\">"));
181
0
  output.append(LOG4CXX_EOL);
182
0
  output.append(LOG4CXX_STR("<html>"));
183
0
  output.append(LOG4CXX_EOL);
184
0
  output.append(LOG4CXX_STR("<head>"));
185
0
  output.append(LOG4CXX_EOL);
186
0
  output.append(LOG4CXX_STR("<title>"));
187
0
  Transform::appendEscapingTags(output, m_priv->title);
188
0
  output.append(LOG4CXX_STR("</title>"));
189
0
  output.append(LOG4CXX_EOL);
190
0
  output.append(LOG4CXX_STR("<style type=\"text/css\">"));
191
0
  output.append(LOG4CXX_EOL);
192
0
  output.append(LOG4CXX_STR("<!--"));
193
0
  output.append(LOG4CXX_EOL);
194
0
  output.append(LOG4CXX_STR("body, table {font-family: arial,sans-serif; font-size: x-small;}"));
195
0
  output.append(LOG4CXX_EOL);
196
0
  output.append(LOG4CXX_STR("th {background: #336699; color: #FFFFFF; text-align: left;}"));
197
0
  output.append(LOG4CXX_EOL);
198
0
  output.append(LOG4CXX_STR("-->"));
199
0
  output.append(LOG4CXX_EOL);
200
0
  output.append(LOG4CXX_STR("</style>"));
201
0
  output.append(LOG4CXX_EOL);
202
0
  output.append(LOG4CXX_STR("</head>"));
203
0
  output.append(LOG4CXX_EOL);
204
0
  output.append(LOG4CXX_STR("<body bgcolor=\"#FFFFFF\" topmargin=\"6\" leftmargin=\"6\">"));
205
0
  output.append(LOG4CXX_EOL);
206
0
  output.append(LOG4CXX_STR("<hr size=\"1\" noshade>"));
207
0
  output.append(LOG4CXX_EOL);
208
0
  output.append(LOG4CXX_STR("Log session start time "));
209
210
0
  m_priv->dateFormat.format(output, Date::currentTime(), p);
211
212
0
  output.append(LOG4CXX_STR("<br>"));
213
0
  output.append(LOG4CXX_EOL);
214
0
  output.append(LOG4CXX_STR("<br>"));
215
0
  output.append(LOG4CXX_EOL);
216
0
  output.append(LOG4CXX_STR("<table cellspacing=\"0\" cellpadding=\"4\" border=\"1\" bordercolor=\"#224466\" width=\"100%\">"));
217
0
  output.append(LOG4CXX_EOL);
218
0
  output.append(LOG4CXX_STR("<tr>"));
219
0
  output.append(LOG4CXX_EOL);
220
0
  output.append(LOG4CXX_STR("<th>Time</th>"));
221
0
  output.append(LOG4CXX_EOL);
222
0
  output.append(LOG4CXX_STR("<th>Thread</th>"));
223
0
  output.append(LOG4CXX_EOL);
224
0
  output.append(LOG4CXX_STR("<th>Level</th>"));
225
0
  output.append(LOG4CXX_EOL);
226
0
  output.append(LOG4CXX_STR("<th>Logger</th>"));
227
0
  output.append(LOG4CXX_EOL);
228
229
0
  if (m_priv->locationInfo)
230
0
  {
231
0
    output.append(LOG4CXX_STR("<th>File:Line</th>"));
232
0
    output.append(LOG4CXX_EOL);
233
0
  }
234
235
0
  output.append(LOG4CXX_STR("<th>Message</th>"));
236
0
  output.append(LOG4CXX_EOL);
237
0
  output.append(LOG4CXX_STR("</tr>"));
238
0
  output.append(LOG4CXX_EOL);
239
0
}
240
241
void HTMLLayout::appendFooter(LogString& output, Pool& /* pool */ )
242
0
{
243
0
  output.append(LOG4CXX_STR("</table>"));
244
0
  output.append(LOG4CXX_EOL);
245
0
  output.append(LOG4CXX_STR("<br>"));
246
0
  output.append(LOG4CXX_EOL);
247
0
  output.append(LOG4CXX_STR("</body></html>"));
248
0
}
249
250
void HTMLLayout::setLocationInfo(bool locationInfoFlag)
251
0
{
252
0
  m_priv->locationInfo = locationInfoFlag;
253
0
}
254
255
bool HTMLLayout::getLocationInfo() const
256
0
{
257
0
  return m_priv->locationInfo;
258
0
}
259
260
void HTMLLayout::setTitle(const LogString& title1)
261
0
{
262
0
  m_priv->title.assign(title1);
263
0
}
264
265
const LogString& HTMLLayout::getTitle() const
266
0
{
267
0
  return m_priv->title;
268
0
}
269
270
LogString HTMLLayout::getContentType() const
271
0
{
272
0
  return LOG4CXX_STR("text/html");
273
0
}
274
275
bool HTMLLayout::ignoresThrowable() const
276
0
{
277
0
  return false;
278
0
}