-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathdmlog_appender.cpp
103 lines (90 loc) · 2.84 KB
/
dmlog_appender.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <fc/log/dmlog_appender.hpp>
#include <fc/log/log_message.hpp>
#include <fc/string.hpp>
#include <fc/variant.hpp>
#include <fc/reflect/variant.hpp>
#ifndef WIN32
#include <unistd.h>
#include <signal.h>
#endif
#include <boost/asio/io_context.hpp>
#include <boost/thread/mutex.hpp>
#include <fc/exception/exception.hpp>
#include <iomanip>
#include <cstdio>
namespace fc {
class dmlog_appender::impl {
public:
bool is_stopped = false;
FILE* out = nullptr;
bool owns_out = false;
};
dmlog_appender::dmlog_appender( const std::optional<dmlog_appender::config>& args )
:dmlog_appender(){
if (!args || (args->file == "-" || args->file == "-stdout"))
{
my->out = stdout;
}
else if (args->file == "-stderr")
{
my->out = stderr;
}
else
{
my->out = std::fopen(args->file.c_str(), "a");
if (my->out)
{
std::setbuf(my->out, nullptr);
my->owns_out = true;
}
else
{
FC_THROW("Failed to open deep mind log file ${name}", ("name", args->file));
}
}
}
dmlog_appender::dmlog_appender( const variant& args )
:dmlog_appender(args.as<std::optional<config>>()){}
dmlog_appender::dmlog_appender()
:my(new impl){}
dmlog_appender::~dmlog_appender() {
if (my->owns_out)
{
std::fclose(my->out);
}
}
void dmlog_appender::initialize() {}
void dmlog_appender::log( const log_message& m ) {
FILE* out = my->out;
std::string message = format_string( "DMLOG " + m.get_format() + "\n", m.get_data() );
auto remaining_size = message.size();
auto message_ptr = message.c_str();
while (!my->is_stopped && remaining_size) {
auto written = fwrite(message_ptr, sizeof(char), remaining_size, out);
// EINTR shouldn't happen anymore, but keep this detection, just in case.
if(written == 0 && errno != EINTR)
{
my->is_stopped = true;
}
if(written != remaining_size)
{
fprintf(stderr, "DMLOG FPRINTF_FAILED failed written=%lu remaining=%lu %d %s\n", written, remaining_size, ferror(out), strerror(errno));
clearerr(out);
}
if(my->is_stopped)
{
fprintf(stderr, "DMLOG FPRINTF_FAILURE_TERMINATED\n");
// Depending on the error, we might have already gotten a SIGPIPE
// An extra signal is harmless, though. Use a process targeted
// signal (not raise) because the SIGTERM may be blocked in this
// thread.
kill(getpid(), SIGTERM);
}
message_ptr = &message_ptr[written];
remaining_size -= written;
}
// attempt a flush, ignore any error
if (!my->is_stopped)
fflush(my->out);
}
}