Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
console_appender.cpp
Go to the documentation of this file.
3#include <fc/string.hpp>
4#include <fc/variant.hpp>
6#ifndef WIN32
7#include <unistd.h>
8#endif
9#define COLOR_CONSOLE 1
10#include "console_defines.h"
12#include <iomanip>
13#include <mutex>
14#include <sstream>
15
16
17namespace fc {
18
20 public:
23 bool use_syslog_header{getenv("JOURNAL_STREAM") != nullptr};
24#ifdef WIN32
25 HANDLE console_handle;
26#endif
27 };
28
30 :my(new impl)
31 {
32 configure( args.as<config>() );
33 }
34
36 :my(new impl)
37 {
38 configure( cfg );
39 }
42
43
44 void console_appender::configure( const config& console_appender_config )
45 { try {
46#ifdef WIN32
47 my->console_handle = INVALID_HANDLE_VALUE;
48#endif
49 my->cfg = console_appender_config;
50#ifdef WIN32
51 if (my->cfg.stream == stream::std_error)
52 my->console_handle = GetStdHandle(STD_ERROR_HANDLE);
53 else if (my->cfg.stream == stream::std_out)
54 my->console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
55#endif
56
57 for( int i = 0; i < log_level::off+1; ++i )
58 my->lc[i] = color::console_default;
59 for( auto itr = my->cfg.level_colors.begin(); itr != my->cfg.level_colors.end(); ++itr )
60 my->lc[itr->level] = itr->color;
61 } FC_CAPTURE_AND_RETHROW( (console_appender_config) ) }
62
64
65 #ifdef WIN32
66 static WORD
67 #else
68 static const char*
69 #endif
70 get_console_color(console_appender::color::type t ) {
71 switch( t ) {
72 case console_appender::color::red: return CONSOLE_RED;
73 case console_appender::color::green: return CONSOLE_GREEN;
74 case console_appender::color::brown: return CONSOLE_BROWN;
75 case console_appender::color::blue: return CONSOLE_BLUE;
76 case console_appender::color::magenta: return CONSOLE_MAGENTA;
77 case console_appender::color::cyan: return CONSOLE_CYAN;
78 case console_appender::color::white: return CONSOLE_WHITE;
80 default:
81 return CONSOLE_DEFAULT;
82 }
83 }
84
85 string fixed_size( size_t s, const string& str ) {
86 if( str.size() == s ) return str;
87 if( str.size() > s ) return str.substr( 0, s );
88 string tmp = str;
89 tmp.append( s - str.size(), ' ' );
90 return tmp;
91 }
92
94 //fc::string message = fc::format_string( m.get_format(), m.get_data() );
95 //fc::variant lmsg(m);
96
97 FILE* out = my->cfg.stream == stream::std_error ? stderr : stdout;
98
99 //fc::string fmt_str = fc::format_string( cfg.format, mutable_variant_object(m.get_context())( "message", message) );
100
101 const log_context context = m.get_context();
102 std::string file_line = context.get_file().substr( 0, 22 );
103 file_line += ':';
104 file_line += fixed_size( 6, fc::to_string( context.get_line_number() ) );
105
106 std::string line;
107 line.reserve( 256 );
108 if(my->use_syslog_header) {
109 switch(m.get_context().get_log_level()) {
110 case log_level::error:
111 line += "<3>";
112 break;
113 case log_level::warn:
114 line += "<4>";
115 break;
116 case log_level::info:
117 line += "<6>";
118 break;
119 case log_level::debug:
120 line += "<7>";
121 break;
122 }
123 }
124 line += fixed_size( 5, context.get_log_level().to_string() ); line += ' ';
125 // use now() instead of context.get_timestamp() because log_message construction can include user provided long running calls
126 line += string( time_point::now() ); line += ' ';
127 line += fixed_size( 9, context.get_thread_name() ); line += ' ';
128 line += fixed_size( 29, file_line ); line += ' ';
129
130 auto me = context.get_method();
131 // strip all leading scopes...
132 if( me.size() ) {
133 uint32_t p = 0;
134 for( uint32_t i = 0;i < me.size(); ++i ) {
135 if( me[i] == ':' ) p = i;
136 }
137
138 if( me[p] == ':' ) ++p;
139 line += fixed_size( 20, context.get_method().substr( p, 20 ) ); line += ' ';
140 }
141 line += "] ";
142 line += fc::format_string( m.get_format(), m.get_data() );
143
144 print( line, my->lc[context.get_log_level()] );
145
146 fprintf( out, "\n" );
147
148 if( my->cfg.flush ) fflush( out );
149 }
150
151 void console_appender::print( const std::string& text, color::type text_color )
152 {
153 FILE* out = my->cfg.stream == stream::std_error ? stderr : stdout;
154
155 #ifdef WIN32
156 if (my->console_handle != INVALID_HANDLE_VALUE)
157 SetConsoleTextAttribute(my->console_handle, get_console_color(text_color));
158 #else
159 if(isatty(fileno(out))) fprintf( out, "%s", get_console_color( text_color ) );
160 #endif
161
162 if( text.size() )
163 fprintf( out, "%s", text.c_str() ); //fmt_str.c_str() );
164
165 #ifdef WIN32
166 if (my->console_handle != INVALID_HANDLE_VALUE)
167 SetConsoleTextAttribute(my->console_handle, CONSOLE_DEFAULT);
168 #else
169 if(isatty(fileno(out))) fprintf( out, "%s", CONSOLE_DEFAULT );
170 #endif
171
172 if( my->cfg.flush ) fflush( out );
173 }
174
175}
const mie::Vuint & p
Definition bn.cpp:27
color::type lc[log_level::off+1]
virtual void log(const log_message &m)
void print(const std::string &text_to_print, color::type text_color=color::console_default)
void configure(const config &cfg)
provides information about where and when a log message was generated.
log_level get_log_level() const
aggregates a message along with the context and associated meta-information.
log_context get_context() const
string get_format() const
variant_object get_data() const
static time_point now()
Definition time.cpp:14
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
T as() const
Definition variant.hpp:327
Defines exception's used by fc.
#define FC_CAPTURE_AND_RETHROW(...)
Defines types and helper macros necessary for generating log messages.
namespace sysio::chain
Definition authority.cpp:3
std::string string
Definition string.hpp:10
fc::string to_string(double)
Definition string.cpp:131
string fixed_size(size_t s, const string &str)
fc::string format_string(const fc::string &, const variant_object &, bool minimize=false)
Definition variant.cpp:773
unsigned int uint32_t
Definition stdint.h:126
char * s