Ceph日志归档

Ceph日志管理

Ceph产生的日志是怎么进行归档或者处理的呢?

在Linux下,基本上都是使用logrotate日志管理工具来处理日志的。关于logrotate的详解可以通过这篇文章了解: http://www.ywnds.com/?p=5471

关于Ceph的日志处理的logrotate的配置,可以查看/etc/logrotate.d/ceph文件,源码中的话在ceph/src/logrotate.conf中。

我们来看一下这个配置文件:

/var/log/ceph/*.log {
    rotate 7
    daily
    compress
    sharedscripts
    postrotate
        killall -q -1 ceph-mon ceph-mds ceph-osd ceph-fuse radosgw || true
    endscript
    missingok
    notifempty
    su root ceph
}

从上面的这个logrotate配置中,我们可以看出:

Ceph日志是保留7天;

每天做一次压缩、转储;

其中的命令:

postrotate
    killall -q -1 ceph-mon ceph-mds ceph-osd ceph-fuse radosgw || true

postrotate是指每次做完转储之后要做的命令。killall这条命令就是要执行的。

乍一看这条命令,为什么是向ceph的那些进程发送信号呢,岂不是关掉那些进程吗。

killall的命令中-1就是具体的信号,通过man 7 SIGNAL可以看到信号1就是SIGHUB信号,默认SIGHUP信号的处理是直接中断服务的。

难道真是停止所有ceph服务吗?肯定不对,我们就去看看ceph-mon ceph-osd的代码,看怎么处理这个信号的。

ceph-mon ceph-osd服务的入口函数都是ceph_mon.cc或者ceph_osd.cc,下面我们以ceph-osd服务来看:

ceph_osd.cc:

int main(int argc, const char **argv)
{
    ...
    register_async_signal_handler(SIGHUP, sighup_handler);
    ...
    unregister_async_signal_handler(SIGHUP, sighup_handler);
    ...
    
}

从main函数中可见,注册了一个信号处理函数,对SIGHUP信号进行处理,回调处理函数是sighup_handler:

void sighup_handler(int signum) 
{                               
  g_ceph_context->reopen_logs();
}

reopen_logs函数如下:

void CephContext::reopen_logs()           
{                                         
  ceph_spin_lock(&_service_thread_lock);  
  if (_service_thread)                    
    _service_thread->reopen_logs();       
  ceph_spin_unlock(&_service_thread_lock);
}

然后调用到了reopen_logs:

void reopen_logs()       
{                        
  Mutex::Locker l(_lock);
  _reopen_logs = true;   
  _cond.Signal();        
}

该函数中,将_reopen_logs这个变量设置为true,并且,唤醒了等待_cond的函数。

通过搜索_reopen_logs变量,可以看到在如下的函数中处理:

void *entry()                                              
{                                                          
  while (1) {   
    if (_cct->_conf->heartbeat_interval) {                 
      utime_t interval(_cct->_conf->heartbeat_interval, 0);
      _cond.WaitInterval(_cct, _lock, interval);           
    } else                                                 
      _cond.Wait(_lock);                                   
  
    if (_reopen_logs) {                                    
      _cct->_log->reopen_log_file();                       
      _reopen_logs = false;                                
    }                                                      
    ...
}

该函数是CephContextServiceThread类型的thread的线程入口函数,在死循环中,会根据heartbeat时间间隔,来进行心跳处理,同时,也在等待_cond这个条件变量,上面的reopen_logs函数唤醒的就是这个。进而,调用了reopen_log_file()函数。

这里的reopen_log_file是具体的reopen log函数:

void Log::reopen_log_file()
{
   if (m_fd >= 0)                                                           
     VOID_TEMP_FAILURE_RETRY(::close(m_fd));                                
   if (m_log_file.length()) {                                               
     m_fd = ::open(m_log_file.c_str(), O_CREAT|O_WRONLY|O_APPEND, 0644);    
     if (m_fd >= 0 && (m_uid || m_gid)) {                                   
       int r = ::fchown(m_fd, m_uid, m_gid);                                
       if (r < 0) {                                                         
         r = -errno;                                                        
         cerr << "failed to chown " << m_log_file << ": " << cpp_strerror(r)
          << std::endl;                                                     
       }                                                                    
     }                                                                      
   } else {                                                                 
     m_fd = -1;                                                             
   }                                                                                                        
}

先看fd是否有效,否则,就创建m_log_file, m_log_file就是具体的log路径及文件名。

你可能感兴趣的:(分布式存储,ceph)