Fabcoin Core  0.16.2
P2P Digital Currency
Log.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include "Log.h"
23 
24 #include <string>
25 #include <iostream>
26 #include <thread>
27 #ifdef __APPLE__
28 #include <pthread.h>
29 #endif
30 #include "Guards.h"
31 using namespace std;
32 using namespace dev;
33 
34 //⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙
35 
36 // Logging
39 
43 static map<type_info const*, bool> s_logOverride;
44 
45 bool dev::isChannelVisible(std::type_info const* _ch, bool _default)
46 {
48  if (s_logOverride.count(_ch))
49  return s_logOverride[_ch];
50  return _default;
51 }
52 
53 LogOverrideAux::LogOverrideAux(std::type_info const* _ch, bool _value):
54  m_ch(_ch)
55 {
57  m_old = s_logOverride.count(_ch) ? (int)s_logOverride[_ch] : c_null;
58  s_logOverride[m_ch] = _value;
59 }
60 
62 {
64  if (m_old == c_null)
65  s_logOverride.erase(m_ch);
66  else
67  s_logOverride[m_ch] = (bool)m_old;
68 }
69 
70 #if defined(_WIN32)
71 const char* LogChannel::name() { return EthGray "..."; }
72 const char* LeftChannel::name() { return EthNavy "<--"; }
73 const char* RightChannel::name() { return EthGreen "-->"; }
74 const char* WarnChannel::name() { return EthOnRed EthBlackBold " X"; }
75 const char* NoteChannel::name() { return EthBlue " i"; }
76 const char* DebugChannel::name() { return EthWhite " D"; }
77 const char* TraceChannel::name() { return EthGray "..."; }
78 #else
79 const char* LogChannel::name() { return EthGray "···"; }
80 const char* LeftChannel::name() { return EthNavy "◀▬▬"; }
81 const char* RightChannel::name() { return EthGreen "▬▬▶"; }
82 const char* WarnChannel::name() { return EthOnRed EthBlackBold " ✘"; }
83 const char* NoteChannel::name() { return EthBlue " ℹ"; }
84 const char* DebugChannel::name() { return EthWhite " ◇"; }
85 const char* TraceChannel::name() { return EthGray "..."; }
86 #endif
87 
88 LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing):
89  m_autospacing(_autospacing),
90  m_verbosity(_v)
91 {
93  auto it = s_logOverride.find(_info);
94  if ((it != s_logOverride.end() && it->second == true) || (it == s_logOverride.end() && (int)_v <= g_logVerbosity))
95  {
96  time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
97  unsigned ms = chrono::duration_cast<chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 1000;
98  char buf[24];
99  if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0)
100  buf[0] = '\0'; // empty if case strftime fails
101  static char const* c_begin = " " EthViolet;
102  static char const* c_sep1 = EthReset EthBlack "|" EthNavy;
103  static char const* c_sep2 = EthReset EthBlack "|" EthTeal;
104  static char const* c_end = EthReset " ";
105  m_sstr << _id << c_begin << buf << "." << setw(3) << setfill('0') << ms;
106  m_sstr << c_sep1 << getThreadName() << ThreadContext::join(c_sep2) << c_end;
107  }
108 }
109 
112 {
113  ThreadLocalLogName(std::string const& _name) { m_name.reset(new string(_name)); }
114  boost::thread_specific_ptr<std::string> m_name;
115 };
116 
119 {
120  ThreadLocalLogContext() = default;
121 
122  void push(std::string const& _name)
123  {
124  if (!m_contexts.get())
125  m_contexts.reset(new vector<string>);
126  m_contexts->push_back(_name);
127  }
128 
129  void pop()
130  {
131  m_contexts->pop_back();
132  }
133 
134  string join(string const& _prior)
135  {
136  string ret;
137  if (m_contexts.get())
138  for (auto const& i: *m_contexts)
139  ret += _prior + i;
140  return ret;
141  }
142 
143  boost::thread_specific_ptr<std::vector<std::string>> m_contexts;
144 };
145 
147 
149 
150 void dev::ThreadContext::push(string const& _n)
151 {
152  g_logThreadContext.push(_n);
153 }
154 
156 {
157  g_logThreadContext.pop();
158 }
159 
160 string dev::ThreadContext::join(string const& _prior)
161 {
162  return g_logThreadContext.join(_prior);
163 }
164 
165 // foward declare without all of Windows.h
166 #if defined(_WIN32)
167 extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* lpOutputString);
168 #endif
169 
171 {
172 #ifdef FASC_BUILD
173  return "";
174 #else
175 #if defined(__GLIBC__) || defined(__APPLE__)
176  char buffer[128];
177  pthread_getname_np(pthread_self(), buffer, 127);
178  buffer[127] = 0;
179  return buffer;
180 #else
181  return g_logThreadName.m_name.get() ? *g_logThreadName.m_name.get() : "<unknown>";
182 #endif
183 #endif
184 }
185 
186 void dev::setThreadName(string const& _n)
187 {
188 #ifndef FASC_BUILD
189 #if defined(__GLIBC__)
190  pthread_setname_np(pthread_self(), _n.c_str());
191 #elif defined(__APPLE__)
192  pthread_setname_np(_n.c_str());
193 #else
194  g_logThreadName.m_name.reset(new std::string(_n));
195 #endif
196 #endif
197 }
198 
199 void dev::simpleDebugOut(std::string const& _s, char const*)
200 {
201  static SpinLock s_lock;
202  SpinGuard l(s_lock);
203 
204  cerr << _s << endl << flush;
205 
206  // helpful to use OutputDebugString on windows
207  #if defined(_WIN32)
208  {
209  OutputDebugStringA(_s.data());
210  OutputDebugStringA("\n");
211  }
212  #endif
213 }
214 
215 std::function<void(std::string const&, char const*)> dev::g_logPost = simpleDebugOut;
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
std::type_info const * m_ch
Definition: Log.h:63
static void pop()
Definition: Log.cpp:155
ThreadLocalLogContext g_logThreadContext
Definition: Log.cpp:146
static const int c_null
Definition: Log.h:64
void simpleDebugOut(std::string const &, char const *)
A simple log-output function that prints log messages to stdout.
Definition: Log.cpp:199
ThreadLocalLogName(std::string const &_name)
Definition: Log.cpp:113
void push(std::string const &_name)
Definition: Log.cpp:122
size_t count
Definition: ExecStats.cpp:37
bool isChannelVisible(std::type_info const *_ch, bool _default)
Definition: Log.cpp:45
#define EthGreen
Definition: Terminal.h:122
std::hash for asio::adress
Definition: Common.h:323
#define EthBlackBold
Definition: Terminal.h:133
static const char * name()
Definition: Log.cpp:81
Simple lock that waits for release without making context switch.
Definition: Guards.h:73
std::stringstream m_sstr
The accrued log entry.
Definition: Log.h:254
Associate a name with each thread for nice logging.
Definition: Log.cpp:111
ThreadLocalLogName g_logThreadName("main")
static const char * name()
Definition: Log.cpp:80
LogOutputStreamBase(char const *_id, std::type_info const *_info, unsigned _v, bool _autospacing)
Definition: Log.cpp:88
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
std::function< void(std::string const &, char const *)> g_logPost
The current method that the logging system uses to output the log messages. Defaults to simpleDebugOu...
Definition: Log.cpp:215
#define EthWhite
Definition: Terminal.h:119
void setThreadName(std::string const &_n)
Set the current thread&#39;s log name.
#define EthGray
Definition: Terminal.h:118
std::string getThreadName()
Set the current thread&#39;s log name.
Definition: Log.cpp:170
std::lock_guard< SpinLock > SpinGuard
Definition: Guards.h:82
mutex x_logOverride
Definition: Log.cpp:38
static const char * name()
Definition: Log.cpp:84
static std::string join(std::string const &_prior)
Definition: Log.cpp:160
int g_logVerbosity
The logging system&#39;s current verbosity.
Definition: Log.cpp:37
boost::thread_specific_ptr< std::vector< std::string > > m_contexts
Definition: Log.cpp:143
#define EthViolet
Definition: Terminal.h:128
static void push(std::string const &_n)
Definition: Log.cpp:150
static const char * name()
Definition: Log.cpp:82
#define EthNavy
Definition: Terminal.h:126
#define EthBlack
Definition: Terminal.h:116
#define EthTeal
Definition: Terminal.h:130
static const char * name()
Definition: Log.cpp:83
string join(string const &_prior)
Definition: Log.cpp:134
Associate a name with each thread for nice logging.
Definition: Log.cpp:118
#define EthBlue
Definition: Terminal.h:127
#define EthOnRed
Definition: Terminal.h:172
__declspec(dllimport)
Definition: util_win32.c:26
static const char * name()
Definition: Log.cpp:85
#define EthReset
Definition: Terminal.h:80
boost::thread_specific_ptr< std::string > m_name
Definition: Log.cpp:114
static const char * name()
Definition: Log.cpp:79