1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef __CEPH_LOG_LOG_H
5 #define __CEPH_LOG_LOG_H
7 #include <boost/circular_buffer.hpp>
9 #include <condition_variable>
14 #include <string_view>
16 #include "common/Thread.h"
17 #include "common/likely.h"
19 #include "log/Entry.h"
30 class Log
: private Thread
32 using EntryRing
= boost::circular_buffer
<ConcreteEntry
>;
33 using EntryVector
= std::vector
<ConcreteEntry
>;
35 static const std::size_t DEFAULT_MAX_NEW
= 100;
36 static const std::size_t DEFAULT_MAX_RECENT
= 10000;
38 Log
**m_indirect_this
;
40 const SubsystemMap
*m_subs
;
42 std::mutex m_queue_mutex
;
43 std::mutex m_flush_mutex
;
44 std::condition_variable m_cond_loggers
;
45 std::condition_variable m_cond_flusher
;
47 pthread_t m_queue_mutex_holder
;
48 pthread_t m_flush_mutex_holder
;
50 EntryVector m_new
; ///< new entries
51 EntryRing m_recent
; ///< recent (less new) entries we've already written at low detail
52 EntryVector m_flush
; ///< entries to be flushed (here to optimize heap allocations)
54 std::string m_log_file
;
59 int m_fd_last_error
= 0; ///< last error we say writing to fd (if any)
61 int m_syslog_log
= -2, m_syslog_crash
= -2;
62 int m_stderr_log
= -1, m_stderr_crash
= -1;
63 int m_graylog_log
= -3, m_graylog_crash
= -3;
64 int m_journald_log
= -3, m_journald_crash
= -3;
66 std::string m_log_stderr_prefix
;
68 std::shared_ptr
<Graylog
> m_graylog
;
69 std::unique_ptr
<JournaldLogger
> m_journald
;
71 std::vector
<char> m_log_buf
;
75 std::size_t m_max_new
= DEFAULT_MAX_NEW
;
76 std::size_t m_max_recent
= DEFAULT_MAX_RECENT
;
78 bool m_inject_segv
= false;
80 void *entry() override
;
82 void _log_safe_write(std::string_view sv
);
84 void _flush(EntryVector
& q
, bool crash
);
86 void _log_message(std::string_view s
, bool crash
);
89 using Thread::is_started
;
91 Log(const SubsystemMap
*s
);
94 void set_flush_on_exit();
96 void set_coarse_timestamps(bool coarse
);
97 void set_max_new(std::size_t n
);
98 void set_max_recent(std::size_t n
);
99 void set_log_file(std::string_view fn
);
100 void reopen_log_file();
101 void chown_log_file(uid_t uid
, gid_t gid
);
102 void set_log_stderr_prefix(std::string_view p
);
108 void set_syslog_level(int log
, int crash
);
109 void set_stderr_level(int log
, int crash
);
110 void set_graylog_level(int log
, int crash
);
112 void start_graylog(const std::string
& host
,
116 void set_journald_level(int log
, int crash
);
118 void start_journald_logger();
119 void stop_journald_logger();
121 std::shared_ptr
<Graylog
> graylog() { return m_graylog
; }
123 void submit_entry(Entry
&& e
);
128 /// true if the log lock is held by our thread
129 bool is_inside_log_lock();
131 /// induce a segv on the next log event