日志器代码
log.h
#ifndef __SYLAR_LOG_H__
#define __SYLAR_LOG_H__
#include "singletojn.h"
#include "util.h"
#include <cstdarg>
#include <sched.h>
#include <string>
#include <stdint.h>
#include <memory>
#include <list>
#include <sstream>
#include <fstream>
#include <iostream>
#include <vector>
#include <map>
#define SYLAR_LOG_LEVEL(logger, level) \
if (logger->getLevel() <= level) \
sylar::LogEventWrap( \
sylar::LogEvent::ptr(new sylar::LogEvent( \
logger, level, __FILE__, __LINE__, 0, sylar::GetThreadId(), \
sylar::GetFiberId(), time(0)))).getSS()
#define SYLAR_LOG_DEBUG(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::DEBUG)
#define SYLAR_LOG_INFO(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::INFO)
#define SYLAR_LOG_WARN(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::WARN)
#define SYLAR_LOG_ERROR(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::ERROR)
#define SYLAR_LOG_FATAL(logger) SYLAR_LOG_LEVEL(logger, sylar::LogLevel::FATAL)
#define SYLAR_LOG_FMT_LEVEL(logger, level, fmt, ...) \
if (logger->getLevel() <= level) \
sylar::LogEventWrap( \
sylar::LogEvent::ptr(new sylar::LogEvent( \
logger, level, __FILE__, __LINE__, 0, sylar::GetThreadId(), \
sylar::GetFiberId(), time(0)))) \
.getEvent() \
->format(fmt, __VA_ARGS__)
#define SYLAR_LOG_FMT_DEBUG(logger, fmt, ...) \
SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::DEBUG, fmt, __VA_ARGS__)
#define SYLAR_LOG_FMT_INFO(logger, fmt, ...) \
SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::INFO, fmt, __VA_ARGS__)
#define SYLAR_LOG_FMT_WARN(logger, fmt, ...) \
SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::WARN, fmt, __VA_ARGS__)
#define SYLAR_LOG_FMT_ERROR(logger, fmt, ...) \
SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::ERROR, fmt, __VA_ARGS__)
#define SYLAR_LOG_FMT_FATAL(logger, fmt, ...) \
SYLAR_LOG_FMT_LEVEL(logger, sylar::LogLevel::FATAL, fmt, __VA_ARGS__)
namespace sylar{
class Logger;
//日志级别
class LogLevel{
public:
enum Level
{
UNKNOW=0,
DEBUG = 1,
INFO = 2,
WARN = 3,
ERROR = 4,
FATAL = 5,
};
static const char *ToString(LogLevel::Level level);
};
//日志事件
class LogEvent {
public:
typedef std::shared_ptr<LogEvent> ptr;
LogEvent(std::shared_ptr<Logger> logger,LogLevel::Level level,const char *file, int32_t line, uint32_t elapse, uint32_t thread_id, uint32_t fiber_id, uint64_t time);
const char *getFile() const {
return m_file; }
int32_t getLine() const {
return m_line; }
uint32_t getElapse() const {
return m_elapse; }
uint32_t getThreadId() const {
return m_threadId; }
uint32_t getFiberId() const {
return m_fiberId; }
uint64_t getTime() const {
return m_time; }
std::string getContent() const {
return m_ss.str(); }
std::stringstream &getSS() {
return m_ss; }
std::shared_ptr<Logger> getLogger()const{
return m_logger;}
LogLevel::Level getLevel() const {
return m_level; }
void format(const char *fmt, ...);
void format(const char *fmt,va_list al);
private:
const char *m_file = nullptr; //文件名
int32_t m_line = 0; // 行号
uint32_t m_elapse = 0; //程序启动开始到现在的毫秒数
uint32_t m_threadId = 0; //线程id
uint32_t m_fiberId = 0; //协程
uint32_t m_time = 0; //时间戳
std::stringstream m_ss;
std::shared_ptr<Logger> m_logger;
LogLevel::Level m_level;
};
class LogEventWrap {
//wrap作为临时对象,使用完后直接析构出发日志写入,由于日志本身的智能指针,如果声明再主函数里面,程序不结束就永远无法释放
public:
LogEventWrap(LogEvent::ptr e);
~LogEventWrap();
LogEvent::ptr getEvent()const{
return m_event;}
std::stringstream &getSS();
private:
LogEvent::ptr m_event