blob: 6d2e3dd82f68ef0caa5feba676f6efa8117b670b [file] [log] [blame]
Neale Ranns812ed392017-10-16 04:20:13 -07001/*
2 * Copyright (c) 2017 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef __VOM_LOGGER_H__
17#define __VOM_LOGGER_H__
18
19#include <fstream>
20#include <iostream>
Neale Rannsa2ee0292017-11-28 22:29:13 -080021#include <sstream>
Neale Ranns812ed392017-10-16 04:20:13 -070022
23#include "vom/enum_base.hpp"
24
25namespace VOM {
26struct log_level_t : enum_base<log_level_t>
27{
28 const static log_level_t CRITICAL;
29 const static log_level_t ERROR;
30 const static log_level_t WARNING;
31 const static log_level_t INFO;
32 const static log_level_t DEBUG;
33
34private:
35 /**
36 * Private constructor taking the value and the string name
37 */
38 log_level_t(int v, const std::string& s);
Neale Rannsa2ee0292017-11-28 22:29:13 -080039
40 /*
41 * not allowed to construct
42 */
43 log_level_t() = delete;
Neale Ranns812ed392017-10-16 04:20:13 -070044};
45
46/**
47 * Ideally we'd use the boost logger but that is not prevelent
48 * in many distros. So something simple here instead.
49 */
50class log_t
51{
52public:
53 /**
Neale Rannsa2ee0292017-11-28 22:29:13 -080054 *
Neale Ranns812ed392017-10-16 04:20:13 -070055 */
Neale Rannsa2ee0292017-11-28 22:29:13 -080056 class handler
57 {
58 public:
59 /**
60 * Default Constructor
61 */
62 handler() = default;
63
64 /**
65 * Default Destructor
66 */
67 virtual ~handler() = default;
68
69 /**
70 * Handle a log message
71 */
72 virtual void handle_message(const std::string& file,
73 const int line,
74 const std::string& function,
75 const log_level_t& level,
76 const std::string& message) = 0;
77 };
Neale Ranns812ed392017-10-16 04:20:13 -070078
79 /**
Neale Rannsa2ee0292017-11-28 22:29:13 -080080 * Construct a logger
Neale Ranns812ed392017-10-16 04:20:13 -070081 */
Neale Rannsa2ee0292017-11-28 22:29:13 -080082 log_t(handler* h);
83 log_t();
Neale Ranns812ed392017-10-16 04:20:13 -070084
85 /**
86 * The configured level
87 */
88 const log_level_t& level() const;
89
90 /**
91 * set the logging level
92 */
93 void set(const log_level_t& level);
94
95 /**
96 * set a file to receive the logging data
97 */
Neale Rannsa2ee0292017-11-28 22:29:13 -080098 void set(handler* h);
99
100 /**
101 * An entry in the log
102 */
103 class entry
104 {
105 public:
106 entry(const char* file,
107 const char* function,
108 int line,
109 const log_level_t& level);
110 ~entry();
111
112 std::stringstream& stream();
113
114 private:
115 const std::string m_file;
116 const std::string m_function;
117 const log_level_t m_level;
118 const int m_line;
119
120 std::stringstream m_stream;
121 };
122 /**
123 * Register a log handler to receive the log output
124 */
125 void register_handler(handler& h);
Neale Ranns812ed392017-10-16 04:20:13 -0700126
127private:
Neale Rannsa2ee0292017-11-28 22:29:13 -0800128 void write(const std::string& file,
129 const int line,
130 const std::string& function,
131 const log_level_t& level,
132 const std::string& message);
133
Neale Ranns812ed392017-10-16 04:20:13 -0700134 /**
135 * the configured logging level
136 */
137 log_level_t m_level;
138
139 /**
Neale Rannsa2ee0292017-11-28 22:29:13 -0800140 * Pointer to a registered handler. Null if no handler registerd
141 */
142 handler* m_handler;
143};
144
145class file_handler : public log_t::handler
146{
147public:
148 file_handler(const std::string& ofile);
149 ~file_handler();
150
151 virtual void handle_message(const std::string& file,
152 const int line,
153 const std::string& function,
154 const log_level_t& level,
155 const std::string& message);
156
157private:
158 /**
Neale Ranns812ed392017-10-16 04:20:13 -0700159 * Opened file for debugging
160 */
161 std::ofstream m_file_stream;
Neale Rannsa2ee0292017-11-28 22:29:13 -0800162};
Neale Ranns812ed392017-10-16 04:20:13 -0700163
Neale Rannsa2ee0292017-11-28 22:29:13 -0800164class cout_handler : public log_t::handler
165{
166public:
167 cout_handler() = default;
168 ~cout_handler() = default;
169 virtual void handle_message(const std::string& file,
170 const int line,
171 const std::string& function,
172 const log_level_t& level,
173 const std::string& message);
Neale Ranns812ed392017-10-16 04:20:13 -0700174};
175
176/**
177 * Return a log object into which VPP objects can write
178 */
179log_t& logger();
180
181#define VOM_LOG(lvl) \
182 if (lvl >= logger().level()) \
Neale Rannsa2ee0292017-11-28 22:29:13 -0800183 log_t::entry(__FILE__, __FUNCTION__, __LINE__, lvl).stream()
Neale Ranns812ed392017-10-16 04:20:13 -0700184};
185
186/*
187 * fd.io coding-style-patch-verification: ON
188 *
189 * Local Variables:
190 * eval: (c-set-style "mozilla")
191 * End:
192 */
193
194#endif