1    	// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2    	// vim: ts=8 sw=2 smarttab
3    	
4    	#ifndef __CEPH_LOG_LOG_H
5    	#define __CEPH_LOG_LOG_H
6    	
7    	#include <boost/circular_buffer.hpp>
8    	
9    	#include <condition_variable>
10   	#include <memory>
11   	#include <mutex>
12   	#include <queue>
13   	#include <string>
14   	#include <string_view>
15   	
16   	#include "common/Thread.h"
17   	#include "common/likely.h"
18   	
19   	#include "log/Entry.h"
20   	
21   	namespace ceph {
22   	namespace logging {
23   	
24   	class Graylog;
25   	class SubsystemMap;
26   	
27   	class Log : private Thread
28   	{
29   	  using EntryRing = boost::circular_buffer<ConcreteEntry>;
30   	  using EntryVector = std::vector<ConcreteEntry>;
31   	
32   	  static const std::size_t DEFAULT_MAX_NEW = 100;
33   	  static const std::size_t DEFAULT_MAX_RECENT = 10000;
34   	
35   	  Log **m_indirect_this;
36   	  log_clock clock;
37   	
38   	  const SubsystemMap *m_subs;
39   	
40   	  std::mutex m_queue_mutex;
41   	  std::mutex m_flush_mutex;
42   	  std::condition_variable m_cond_loggers;
43   	  std::condition_variable m_cond_flusher;
44   	
(1) Event member_decl: Class member declaration for "m_queue_mutex_holder".
Also see events: [uninit_member][member_decl][uninit_member]
45   	  pthread_t m_queue_mutex_holder;
(3) Event member_decl: Class member declaration for "m_flush_mutex_holder".
Also see events: [member_decl][uninit_member][uninit_member]
46   	  pthread_t m_flush_mutex_holder;
47   	
48   	  EntryVector m_new;    ///< new entries
49   	  EntryRing m_recent; ///< recent (less new) entries we've already written at low detail
50   	  EntryVector m_flush; ///< entries to be flushed (here to optimize heap allocations)
51   	
52   	  std::string m_log_file;
53   	  int m_fd = -1;
54   	  uid_t m_uid = 0;
55   	  gid_t m_gid = 0;
56   	
57   	  int m_fd_last_error = 0;  ///< last error we say writing to fd (if any)
58   	
59   	  int m_syslog_log = -2, m_syslog_crash = -2;
60   	  int m_stderr_log = -1, m_stderr_crash = -1;
61   	  int m_graylog_log = -3, m_graylog_crash = -3;
62   	
63   	  std::string m_log_stderr_prefix;
64   	
65   	  std::shared_ptr<Graylog> m_graylog;
66   	
67   	  std::vector<char> m_log_buf;
68   	
69   	  bool m_stop = false;
70   	
71   	  std::size_t m_max_new = DEFAULT_MAX_NEW;
72   	  std::size_t m_max_recent = DEFAULT_MAX_RECENT;
73   	
74   	  bool m_inject_segv = false;
75   	
76   	  void *entry() override;
77   	
78   	  void _log_safe_write(std::string_view sv);
79   	  void _flush_logbuf();
80   	  void _flush(EntryVector& q, bool requeue, bool crash);
81   	
82   	  void _log_message(const char *s, bool crash);
83   	
84   	public:
85   	  using Thread::is_started;
86   	
87   	  Log(const SubsystemMap *s);
88   	  ~Log() override;
89   	
90   	  void set_flush_on_exit();
91   	
92   	  void set_coarse_timestamps(bool coarse);
93   	  void set_max_new(std::size_t n);
94   	  void set_max_recent(std::size_t n);
95   	  void set_log_file(std::string_view fn);
96   	  void reopen_log_file();
97   	  void chown_log_file(uid_t uid, gid_t gid);
98   	  void set_log_stderr_prefix(std::string_view p);
99   	
100  	  void flush();
101  	
102  	  void dump_recent();
103  	
104  	  void set_syslog_level(int log, int crash);
105  	  void set_stderr_level(int log, int crash);
106  	  void set_graylog_level(int log, int crash);
107  	
108  	  void start_graylog();
109  	  void stop_graylog();
110  	
111  	  std::shared_ptr<Graylog> graylog() { return m_graylog; }
112  	
113  	  void submit_entry(Entry&& e);
114  	
115  	  void start();
116  	  void stop();
117  	
118  	  /// true if the log lock is held by our thread
119  	  bool is_inside_log_lock();
120  	
121  	  /// induce a segv on the next log event
122  	  void inject_segv();
123  	  void reset_segv();
124  	};
125  	
126  	}
127  	}
128  	
129  	#endif
130