mirror of
https://github.com/ceph/ceph
synced 2025-02-12 13:29:17 +00:00
If we have a long line that has to be dynamically allocated, we need to
adjust m_log_buf_pos accordingly afterward. In particular,
_write_and_copy does this adjustment, which means the later += line_used
is not only unnecessary but very bad, since line_used is > MAX_LOG_BUF.
Simplify all of this by getting rid of _write_and_copy: if we are writing
a big chunk let's just send the whole thing to m_fd and not bother keeping
the tail of it around for later.
Fix _log_safe_write to write the passed buffer, not m_log_buf.
Replace the paranoid check with a simple assert.
Fixes: 65da5ba216
Fixes: https://github.com/ceph/ceph/pull/23422
Signed-off-by: Sage Weil <sage@redhat.com>
116 lines
2.4 KiB
C++
116 lines
2.4 KiB
C++
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
|
// vim: ts=8 sw=2 smarttab
|
|
|
|
#ifndef __CEPH_LOG_LOG_H
|
|
#define __CEPH_LOG_LOG_H
|
|
|
|
#include <memory>
|
|
|
|
#include "common/Thread.h"
|
|
|
|
#include "EntryQueue.h"
|
|
|
|
namespace ceph {
|
|
namespace logging {
|
|
|
|
class Graylog;
|
|
class SubsystemMap;
|
|
class Entry;
|
|
|
|
class Log : private Thread
|
|
{
|
|
Log **m_indirect_this;
|
|
log_clock clock;
|
|
|
|
const SubsystemMap *m_subs;
|
|
|
|
pthread_mutex_t m_queue_mutex;
|
|
pthread_mutex_t m_flush_mutex;
|
|
pthread_cond_t m_cond_loggers;
|
|
pthread_cond_t m_cond_flusher;
|
|
|
|
pthread_t m_queue_mutex_holder;
|
|
pthread_t m_flush_mutex_holder;
|
|
|
|
EntryQueue m_new; ///< new entries
|
|
EntryQueue m_recent; ///< recent (less new) entries we've already written at low detail
|
|
|
|
std::string m_log_file;
|
|
int m_fd;
|
|
uid_t m_uid;
|
|
gid_t m_gid;
|
|
|
|
int m_fd_last_error; ///< last error we say writing to fd (if any)
|
|
|
|
int m_syslog_log, m_syslog_crash;
|
|
int m_stderr_log, m_stderr_crash;
|
|
int m_graylog_log, m_graylog_crash;
|
|
|
|
std::string m_log_stderr_prefix;
|
|
|
|
std::shared_ptr<Graylog> m_graylog;
|
|
|
|
char* m_log_buf; ///< coalescing buffer
|
|
int m_log_buf_pos; ///< where we're at within coalescing buffer
|
|
|
|
bool m_stop;
|
|
|
|
int m_max_new, m_max_recent;
|
|
|
|
bool m_inject_segv;
|
|
|
|
void *entry() override;
|
|
|
|
void _log_safe_write(const char* what, size_t write_len);
|
|
void _flush_logbuf();
|
|
void _flush(EntryQueue *q, EntryQueue *requeue, bool crash);
|
|
|
|
void _log_message(const char *s, bool crash);
|
|
|
|
public:
|
|
Log(const SubsystemMap *s);
|
|
~Log() override;
|
|
|
|
void set_flush_on_exit();
|
|
|
|
void set_coarse_timestamps(bool coarse);
|
|
void set_max_new(int n);
|
|
void set_max_recent(int n);
|
|
void set_log_file(std::string fn);
|
|
void reopen_log_file();
|
|
void chown_log_file(uid_t uid, gid_t gid);
|
|
void set_log_stderr_prefix(const std::string& p);
|
|
|
|
void flush();
|
|
|
|
void dump_recent();
|
|
|
|
void set_syslog_level(int log, int crash);
|
|
void set_stderr_level(int log, int crash);
|
|
void set_graylog_level(int log, int crash);
|
|
|
|
void start_graylog();
|
|
void stop_graylog();
|
|
|
|
std::shared_ptr<Graylog> graylog() { return m_graylog; }
|
|
|
|
Entry *create_entry(int level, int subsys, const char* msg = nullptr);
|
|
Entry *create_entry(int level, int subsys, size_t* expected_size);
|
|
void submit_entry(Entry *e);
|
|
|
|
void start();
|
|
void stop();
|
|
|
|
/// true if the log lock is held by our thread
|
|
bool is_inside_log_lock();
|
|
|
|
/// induce a segv on the next log event
|
|
void inject_segv();
|
|
void reset_segv();
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|