blob: d3c99bfa392b6f69f06959655536b0d0921a955b [file] [log] [blame]
Vadim Iosevichd50ea462017-03-30 16:19:08 +03001/*
2 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#ifndef __debug_h
31#define __debug_h
32
33#include <iostream>
34
35// Severity values are expected to raise from zero
36enum LogSeverity
37{
38 LOG_SEV_ERROR = 0, // Unexpected input/events that may cause server misbehavior
39 LOG_SEV_WARNING = 1, // Suspicious events
40 LOG_SEV_INFO = 2, // Events like command/response
41 LOG_SEV_DEBUG = 3, // Detailed functionality
42 LOG_SEV_VERBOSE = 4 // Excessive debug
43};
44
45#define TRACE_WITH_PREFIX(SEV) \
46 g_LogConfig.ShouldPrint(SEV) && std::cout << LogMsgPrefix(SEV, __FILE__, __LINE__)
47
48#define LOG_ERROR TRACE_WITH_PREFIX(LOG_SEV_ERROR)
49#define LOG_WARNING TRACE_WITH_PREFIX(LOG_SEV_WARNING)
50#define LOG_INFO TRACE_WITH_PREFIX(LOG_SEV_INFO)
51#define LOG_DEBUG TRACE_WITH_PREFIX(LOG_SEV_DEBUG)
52#define LOG_VERBOSE TRACE_WITH_PREFIX(LOG_SEV_VERBOSE)
53
54// *************************************************************************************************
55
56struct LogConfig
57{
58public:
59 LogConfig(LogSeverity maxSeverity, bool bPrintLocation);
60 void SetMaxSeverity(int traceLevel);
61
62 bool ShouldPrint(LogSeverity sev) const { return sev <= m_MaxSeverity; }
63 bool ShouldPrintLocation() const { return m_PrintLocation; }
64
65private:
66
67 LogSeverity m_MaxSeverity;
68 const bool m_PrintLocation;
69
70};
71
72// *************************************************************************************************
73
74extern LogConfig g_LogConfig;
75
76// *************************************************************************************************
77
78class LogMsgPrefix
79{
80 friend std::ostream& operator<<(std::ostream& os, const LogMsgPrefix& prefix);
81
82public:
83
84 LogMsgPrefix(LogSeverity severity, const char* pFile, int line)
85 : Severity(severity), File(pFile), Line(line) {}
86
87private:
88
89 static const char* SeverityToString(LogSeverity sev);
90
91 const LogSeverity Severity;
92 const char* const File;
93 const int Line;
94};
95
96
97// *************************************************************************************************
98// Stream Formatters
99// *************************************************************************************************
100
101// Print a boolean value as a string
102struct BoolStr
103{
104 explicit BoolStr(bool value): Value(value) {}
105 const bool Value;
106};
107
108inline std::ostream& operator<<(std::ostream& os, const BoolStr& boolStr)
109{
110 return os << std::boolalpha << boolStr.Value << std::noboolalpha;
111}
112
113// *************************************************************************************************
114
115// Print a string while displaying newline characters
116struct PlainStr
117{
118 explicit PlainStr(const std::string& value): Value(value) {}
119 const std::string& Value;
120};
121
122inline std::ostream& operator<<(std::ostream& os, const PlainStr& plainStr)
123{
124 for (std::string::const_iterator it = plainStr.Value.begin(); it != plainStr.Value.end(); ++it)
125 {
126 switch (*it)
127 {
128 case '\r': os << "\\r"; break;
129 case '\n': os << "\\n"; break;
130 case '\t': os << "\\t"; break;
131 default: os << *it; break;
132 }
133 }
134
135 return os;
136}
137
138
139#endif