ceph log机制
Log 是每个项目必须的,他是跟踪问题的最直接的依据。Ceph 也设计自己的log机制。
初始化启动log实例,启动log线程。
_log = new ceph::log::Log(&_conf->subsys);
_log->start();
日志的工作函数:
比较简单,交换队列到临时队列t 中,释放条件变量,开始进入_flush的写操作。
void Log::flush()
{
pthread_mutex_lock(&m_flush_mutex);
m_flush_mutex_holder = pthread_self();
pthread_mutex_lock(&m_queue_mutex);
m_queue_mutex_holder = pthread_self();
EntryQueue t;
t.swap(m_new);
pthread_cond_broadcast(&m_cond_loggers);
m_queue_mutex_holder = 0;
pthread_mutex_unlock(&m_queue_mutex);
_flush(&t, &m_recent, false);
// trim
while (m_recent.m_len > m_max_recent) {
delete m_recent.dequeue();
}
m_flush_mutex_holder = 0;
pthread_mutex_unlock(&m_flush_mutex);
}
_flush函数中主要根据subsys 和 其level决定是否写日志,m_subs是负责管理subsys的一个map表。
这个表是如何生成的呢。
注意参数:crash 当dump_recent的才会被调用。
void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash)
{
Entry *e;
while ((e = t->dequeue()) != NULL) {
unsigned sub = e->m_subsys;
bool should_log = crash || m_subs->get_log_level(sub) >= e->m_prio;
bool do_fd = m_fd >= 0 && should_log;
bool do_syslog = m_syslog_crash >= e->m_prio && should_log;
bool do_stderr = m_stderr_crash >= e->m_prio && should_log;
bool do_graylog2 = m_graylog_crash >= e->m_prio && should_log;
e->hint_size();
if (do_fd || do_syslog || do_stderr) {
size_t buflen = 0;
char *buf;
size_t buf_size = 80 + e->size();
bool need_dynamic = buf_size >= 0x10000; //avoids >64K buffers
//allocation at stack
char buf0[need_dynamic ? 1 : buf_size];
if (need_dynamic) {
buf = new char[buf_size];
} else {
buf = buf0;
}
if (crash)
buflen += snprintf(buf, buf_size, "%6d> ", -t->m_len);
buflen += e->m_stamp.sprintf(buf + buflen, buf_size-buflen);
buflen += snprintf(buf + buflen, buf_size-buflen, " %lx %2d ",
(unsigned long)e->m_thread, e->m_prio);
buflen += e->snprintf(buf + buflen, buf_size - buflen - 1);
if (buflen > buf_size - 1) { //paranoid check, buf was declared
//to hold everything
buflen = buf_size - 1;
buf[buflen] = 0;
}
if (do_syslog) {
syslog(LOG_USER|LOG_INFO, "%s", buf);
}
if (do_stderr) {
cerr << buf << std::endl;
}
if (do_fd) {
buf[buflen] = '\n';
int r = safe_write(m_fd, buf, buflen+1);
if (r != m_fd_last_error) {
if (r < 0)
cerr << "problem writing to " << m_log_file
<< ": " << cpp_strerror(r)
<< std::endl;
m_fd_last_error = r;
}
}
if (need_dynamic)
delete[] buf;
}
if (do_graylog2 && m_graylog) {
m_graylog->log_entry(e);
}
requeue->enqueue(e);
}
}
SubsystemMap
负责管理所有的subsys。
_log = new ceph::log::Log(&_conf->subsys);
通过参数将其传入到Log.cc中。
_conf->subsys的初始化工作,如何做的呢?
首先定义了3个宏
定义宏SUBSYS(name, log, gather) 是执行subsys.add(ceph_subsys_##name, STRINGIFY(name), log, gather);
定义宏DEFAULT_SUBSYS(log, gather) 是执行subsys.add(ceph_subsys_, "none", log, gather);
定义宏#define OPTION(a, b, c) 为空
将config_opts.h展开,依次执行subsys.add即可完成,
void md_config_t::init_subsys()
{
#define SUBSYS(name, log, gather)
subsys.add(ceph_subsys_##name, STRINGIFY(name), log, gather);
#define DEFAULT_SUBSYS(log, gather)
subsys.add(ceph_subsys_, "none", log, gather);
#define OPTION(a, b, c)
#include "common/config_opts.h"
#undef OPTION
#undef SUBSYS
#undef DEFAULT_SUBSYS
}
ceph_subsys_##name 的值从哪儿来的呢?同样使用了宏的机制。和上一个宏一样,展开后在enum变量中。
enum config_subsys_id {
ceph_subsys_, // default
#define OPTION(a,b,c)
#define SUBSYS(name, log, gather) \
ceph_subsys_##name,
#define DEFAULT_SUBSYS(log, gather)
#include "common/config_opts.h"
#undef SUBSYS
#undef OPTION
#undef DEFAULT_SUBSYS
ceph_subsys_max
};
如何调用ldout 写日志呢?
#define ldout(cct, v) dout_impl(cct, dout_subsys, v) dout_prefix
Dout_impl 生成了log_entry 写入到日志文件, dout_prefix 标准输出
ceph log机制的更多相关文章
- Oracle Redo Log 机制 小结(转载)
Oracle 的Redo 机制DB的一个重要机制,理解这个机制对DBA来说也是非常重要,之前的Blog里也林林散散的写了一些,前些日子看老白日记里也有说明,所以结合老白日记里的内容,对oracle 的 ...
- 解读Android LOG机制的实现【转】
转自:http://www.cnblogs.com/hoys/archive/2011/09/30/2196199.html http://armboard.taobao.com/ Android提供 ...
- android log机制——输出log【转】
转自:http://blog.csdn.net/tdstds/article/details/19084327 目录(?)[-] 在android Java code中输出log Logprintln ...
- Android中Log机制详解
Android中Log的输出有如下几种: Log.v(String tag, String msg); //VERBOSELog.d(String tag, String msg); ...
- js的线程和同步异步以及console.log机制
项目上线了,闲下来就写写东西吧.积累了好多东西都没有做笔记~挑几个印象深刻的记录一下吧. js的同步异步以及单线程问题: 都知道单线程是js的一大特性.但是通常io(ajax获取服务器数据).用户/浏 ...
- Unity3D Log 收集机制
最近做项目的时候发现,需要有一个完整的log机制.这样不仅方便调试而且方便观察. 一.需求 目前我认为一个完善的log机制应该是这样的. 一.双击定位 二.生命周期是全局的 三.输出包括consloe ...
- android log写入机制
这几天和华为的leader面试了下.感觉不错.关键是小女.不容易.是技术面啊.我说的不容易不是面试不容易,是说在华为写代码的小女不容易.哥走南闯北这么多年,女人代码写的好真不多. 其实在任何时候,只要 ...
- Ceph纠删码编码机制
1 Ceph简述 Ceph是一种性能优越,可靠性和可扩展性良好的统一的分布式云存储系统,提供对象存储.块存储.文件存储三种存储服务.Ceph文件系统中不区分节点中心,在理论上可以实现系统规模的无限扩展 ...
- 理解 OpenStack + Ceph (7): Ceph 的基本操作和常见故障排除方法
本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...
随机推荐
- .NET开发框架(四)-服务器IIS安装教程
Windows Server 2012 R2 配置篇,包括服务器IIS安装.网络负载均衡器安装.ASP.NET Core 安装. 前三篇教程中,我们分享了框架的功能与视频演示介绍(文尾扫码 加入 框架 ...
- Python爬虫的起点
第一章主要讲解爬虫相关的知识如:http.网页.爬虫法律等,让大家对爬虫有了一个比较完善的了解和一些题外的知识点. 今天这篇文章将是我们第二章的第一篇,我们从今天开始就正式进入实战阶段,后面将会有更多 ...
- Jrebel激活服务搭建
前言 因为平时的开发工具是使用IntelliJ IDEA,所以热部署项目代码的时候,使用的Jrebel.因为Jrebel是收费的,所以以前用的时候都是在网上找破解方法(国人通用做法),在网上找到的办法 ...
- ajax请求中 两种csrftoken的发送方法
通过ajax的方式发送两个数据进行加法运算 html页面 <body> <h3>index页面 </h3> <input type="text&qu ...
- Spring MVC源码(一) ----- 启动过程与组件初始化
SpringMVC作为MVC框架近年来被广泛地使用,其与Mybatis和Spring的组合,也成为许多公司开发web的套装.SpringMVC继承了Spring的优点,对业务代码的非侵入性,配置的便捷 ...
- EF 使用遇到过的错误记录备忘
1. is only supported for sorted input in LINQ to Entities The method :只支持排序输入实体LINQ 的方法 是使用skip()时没 ...
- Linux系统下word转pdf,xls转pdf,ppt转pdf
word转换pdf的技术方案,供参考.[doc/docx/ppt/pptx/xls/xlsx均支持转换] 本方案是Java结合shell命令完成,不同于以往的仅依赖java组件转换 ...
- 十代雅阁广东车友群,雅阁广州车友群,深圳雅阁车友群,雅阁微信群、雅阁车友群、十代雅阁交流微信QQ群
最近一直在关注第十代雅阁,不论是普通汽油版本还是油电混动版本都很不错,在网上看到很多评测文章和视频 后续都会整理发布到微信群中. 由于论坛发帖,博客发文都不是很方便,为了及时沟通,先创建了微信群,方便 ...
- 分布式事务(4)---RocketMQ实现分布式事务项目
RocketMQ实现分布式事务 有关RocketMQ实现分布式事务前面写了一篇博客 1.RocketMQ实现分布式事务原理 下面就这个项目做个整体简单介绍,并在文字最下方附上项目Github地址. 一 ...
- GitHub使用整理——从开始到上传项目
前期准备 首先是github官网: https://github.com/ 下载github工具: https://git-for-windows.github.io/ 进入github创建一个新的项 ...