Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
dmlog_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#include <signal.h>
9#endif
10#include <boost/asio/io_context.hpp>
11#include <boost/thread/mutex.hpp>
13#include <iomanip>
14#include <mutex>
15#include <sstream>
16
17namespace fc {
19 public:
20 bool is_stopped = false;
21 FILE* out = nullptr;
22 bool owns_out = false;
23 };
24
25 dmlog_appender::dmlog_appender( const std::optional<dmlog_appender::config>& args )
27 if (!args || args->file == "-")
28 {
29 my->out = stdout;
30 }
31 else
32 {
33 my->out = std::fopen(args->file.c_str(), "a");
34 if (my->out)
35 {
36 std::setbuf(my->out, nullptr);
37 my->owns_out = true;
38 }
39 else
40 {
41 FC_THROW("Failed to open deep mind log file ${name}", ("name", args->file));
42 }
43 }
44 }
45
46 dmlog_appender::dmlog_appender( const variant& args )
47 :dmlog_appender(args.as<std::optional<config>>()){}
48
49 dmlog_appender::dmlog_appender()
50 :my(new impl){}
51
53 if (my->owns_out)
54 {
55 std::fclose(my->out);
56 }
57 }
58
59 void dmlog_appender::initialize( boost::asio::io_service& io_service ) {}
60
62 FILE* out = my->out;
63
64 string message = format_string( "DMLOG " + m.get_format() + "\n", m.get_data() );
65
66 auto remaining_size = message.size();
67 auto message_ptr = message.c_str();
68 while (!my->is_stopped && remaining_size) {
69 auto written = fwrite(message_ptr, sizeof(char), remaining_size, out);
70
71 // EINTR shouldn't happen anymore, but keep this detection, just in case.
72 if(written == 0 && errno != EINTR)
73 {
74 my->is_stopped = true;
75 }
76
77 if(written != remaining_size)
78 {
79 fprintf(stderr, "DMLOG FPRINTF_FAILED failed written=%lu remaining=%lu %d %s\n", written, remaining_size, ferror(out), strerror(errno));
80 clearerr(out);
81 }
82
83 if(my->is_stopped)
84 {
85 fprintf(stderr, "DMLOG FPRINTF_FAILURE_TERMINATED\n");
86 // Depending on the error, we might have already gotten a SIGPIPE
87 // An extra signal is harmless, though. Use a process targeted
88 // signal (not raise) because the SIGTERM may be blocked in this
89 // thread.
90 kill(getpid(), SIGTERM);
91 }
92
93 message_ptr = &message_ptr[written];
94 remaining_size -= written;
95 }
96 }
97}
virtual void initialize(boost::asio::io_service &io_service) override
virtual void log(const log_message &m) override
aggregates a message along with the context and associated meta-information.
string get_format() const
variant_object get_data() const
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
websocketpp::config::asio_tls_client::message_type::ptr message_ptr
Defines exception's used by fc.
Defines types and helper macros necessary for generating log messages.
namespace sysio::chain
Definition authority.cpp:3
fc::string format_string(const fc::string &, const variant_object &, bool minimize=false)
Definition variant.cpp:773
Definition name.hpp:106