BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
console_appender.cpp
Go to the documentation of this file.
2 #include <fc/log/log_message.hpp>
4 #include <fc/variant.hpp>
5 #include <fc/reflect/variant.hpp>
6 #ifndef WIN32
7 #include <unistd.h>
8 #endif
9 #include <boost/thread/mutex.hpp>
10 #define COLOR_CONSOLE 1
11 #include "console_defines.h"
12 #include <fc/io/stdio.hpp>
14 #include <iomanip>
15 #include <sstream>
16 #include <mutex>
17 
18 
19 namespace fc {
20 
22  public:
25 #ifdef WIN32
26  HANDLE console_handle;
27 #endif
28  };
29 
31  :my(new impl)
32  {
34  }
35 
37  :my(new impl)
38  {
39  configure( cfg );
40  }
42  :my(new impl){}
43 
44 
45  void console_appender::configure( const config& console_appender_config )
46  { try {
47 #ifdef WIN32
48  my->console_handle = INVALID_HANDLE_VALUE;
49 #endif
50  my->cfg = console_appender_config;
51 #ifdef WIN32
52  if (my->cfg.stream == stream::std_error)
53  my->console_handle = GetStdHandle(STD_ERROR_HANDLE);
54  else if (my->cfg.stream == stream::std_out)
55  my->console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
56 #endif
57 
58  for( int i = 0; i < log_level::off+1; ++i )
59  my->lc[i] = color::console_default;
60  for( auto itr = my->cfg.level_colors.begin(); itr != my->cfg.level_colors.end(); ++itr )
61  my->lc[itr->level] = itr->color;
62  } FC_CAPTURE_AND_RETHROW( (console_appender_config) ) }
63 
65 
66  #ifdef WIN32
67  static WORD
68  #else
69  static const char*
70  #endif
71  get_console_color(console_appender::color::type t ) {
72  switch( t ) {
73  case console_appender::color::red: return CONSOLE_RED;
74  case console_appender::color::green: return CONSOLE_GREEN;
75  case console_appender::color::brown: return CONSOLE_BROWN;
76  case console_appender::color::blue: return CONSOLE_BLUE;
77  case console_appender::color::magenta: return CONSOLE_MAGENTA;
78  case console_appender::color::cyan: return CONSOLE_CYAN;
79  case console_appender::color::white: return CONSOLE_WHITE;
81  default:
82  return CONSOLE_DEFAULT;
83  }
84  }
85 
86  boost::mutex& log_mutex() {
87  static boost::mutex m; return m;
88  }
89 
91 
92  FILE* out = stream::std_error ? stderr : stdout;
93 
94  std::stringstream file_line;
95  file_line << m.get_context().get_file() <<":"<<m.get_context().get_line_number() <<" ";
96 
98  std::stringstream line;
99  line << (m.get_context().get_timestamp().time_since_epoch().count() % (1000ll*1000ll*60ll*60))/1000 <<"ms ";
100  line << std::setw( 10 ) << std::left << m.get_context().get_thread_name().substr(0,9).c_str() <<" "<<std::setw(30)<< std::left <<file_line.str();
101 
102  auto me = m.get_context().get_method();
103  // strip all leading scopes...
104  if( me.size() )
105  {
106  uint32_t p = 0;
107  for( uint32_t i = 0;i < me.size(); ++i )
108  {
109  if( me[i] == ':' ) p = i;
110  }
111 
112  if( me[p] == ':' ) ++p;
113  line << std::setw( 20 ) << std::left << m.get_context().get_method().substr(p,20).c_str() <<" ";
114  }
115  line << "] ";
116  std::string message = fc::format_string( m.get_format(), m.get_data(), my->cfg.max_object_depth );
117  line << message;
118 
120 
121  print( line.str(), my->lc[m.get_context().get_log_level()] );
122 
123  fprintf( out, "\n" );
124 
125  if( my->cfg.flush ) fflush( out );
126  }
127 
128  void console_appender::print( const std::string& text, color::type text_color )
129  {
130  FILE* out = stream::std_error ? stderr : stdout;
131 
132  #ifdef WIN32
133  if (my->console_handle != INVALID_HANDLE_VALUE)
134  SetConsoleTextAttribute(my->console_handle, get_console_color(text_color));
135  #else
136  if(isatty(fileno(out))) fprintf( out, "\r%s", get_console_color( text_color ) );
137  #endif
138 
139  if( text.size() )
140  fprintf( out, "%s", text.c_str() );
141 
142  #ifdef WIN32
143  if (my->console_handle != INVALID_HANDLE_VALUE)
144  SetConsoleTextAttribute(my->console_handle, CONSOLE_DEFAULT);
145  #else
146  if(isatty(fileno(out))) fprintf( out, "\r%s", CONSOLE_DEFAULT );
147  #endif
148 
149  if( my->cfg.flush ) fflush( out );
150  }
151 
152 }
fc::log_message::get_data
variant_object get_data() const
Definition: log_message.cpp:211
stdio.hpp
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
fc::console_appender::color::green
@ green
Definition: console_appender.hpp:15
fc::console_appender::console_appender
console_appender()
Definition: console_appender.cpp:41
variant.hpp
fc::unique_lock
Definition: unique_lock.hpp:13
fc::console_appender::color::brown
@ brown
Definition: console_appender.hpp:16
fc::console_appender::stream::std_out
@ std_out
Definition: console_appender.hpp:25
fc::console_appender::stream::std_error
@ std_error
Definition: console_appender.hpp:25
fc::log_message::get_format
std::string get_format() const
Definition: log_message.cpp:210
fc::console_appender::configure
void configure(const config &cfg)
Definition: console_appender.cpp:45
fc::log_level::off
@ off
Definition: log_message.hpp:39
fc
Definition: api.hpp:15
fc::log_context::get_log_level
log_level get_log_level() const
Definition: log_message.cpp:162
fc::console_appender::color::console_default
@ console_default
Definition: console_appender.hpp:21
fc::console_appender::color::magenta
@ magenta
Definition: console_appender.hpp:18
fc::console_appender::log
virtual void log(const log_message &m)
Definition: console_appender.cpp:90
fc::log_context::get_thread_name
std::string get_thread_name() const
Definition: log_message.cpp:158
fc::log_mutex
boost::mutex & log_mutex()
Definition: console_appender.cpp:86
FC_MAX_LOG_OBJECT_DEPTH
#define FC_MAX_LOG_OBJECT_DEPTH
Definition: config.hpp:8
fc::log_context::get_line_number
uint64_t get_line_number() const
Definition: log_message.cpp:156
fc::console_appender::color::white
@ white
Definition: console_appender.hpp:20
fc::time_point::time_since_epoch
const microseconds & time_since_epoch() const
Definition: time.hpp:54
fc::console_appender::color::red
@ red
Definition: console_appender.hpp:14
fc::log_context::get_file
std::string get_file() const
Definition: log_message.cpp:155
fc::variant::as
T as(uint32_t max_depth) const
Definition: variant.hpp:337
fc::console_appender::impl::cfg
config cfg
Definition: console_appender.cpp:23
fc::log_context::get_timestamp
time_point get_timestamp() const
Definition: log_message.cpp:161
fc::console_appender::print
void print(const std::string &text_to_print, color::type text_color=color::console_default)
Definition: console_appender.cpp:128
unique_lock.hpp
fc::format_string
std::string format_string(const std::string &, const variant_object &, uint32_t max_object_depth=200)
fc::console_appender::impl::lc
color::type lc[log_level::off+1]
Definition: console_appender.cpp:24
fc::console_appender::color::type
type
Definition: console_appender.hpp:13
console_appender.hpp
fc::log_message
aggregates a message along with the context and associated meta-information.
Definition: log_message.hpp:106
fc::console_appender::color::blue
@ blue
Definition: console_appender.hpp:17
fc::variant
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition: variant.hpp:198
fc::console_appender::impl
Definition: console_appender.cpp:21
exception.hpp
Defines exception's used by fc.
fc::console_appender::color::cyan
@ cyan
Definition: console_appender.hpp:19
fc::microseconds::count
int64_t count() const
Definition: time.hpp:28
fc::console_appender::~console_appender
~console_appender()
Definition: console_appender.cpp:64
fc::log_context::get_method
std::string get_method() const
Definition: log_message.cpp:157
fc::console_appender::config
Definition: console_appender.hpp:37
variant.hpp
fc::log_message::get_context
log_context get_context() const
Definition: log_message.cpp:209
log_message.hpp
Defines types and helper macros necessary for generating log messages.