Nginx源码分析 --时间 日期 日志

1.源码分析-时间

1.1基本数据结构

typedef struct {
    time_t      sec;
    ngx_uint_t  msec;
    ngx_int_t   gmtoff;
} ngx_time_t;

结构成员分析:

ngx_time_t在Nginx里用来表示时间,

成员变量sec和msec分别表示秒数(时间戳)和小数部分的毫秒数。

gmtoff是本地时区相对于UTC/GMT的偏移量,以分钟为单位,例如北京时区是GMT+8,那么gmtoff就是480=8* 60。

1.2操作函数

extern volatile ngx_time_t  *ngx_cached_time;
extern volatile ngx_msec_t  ngx_current_msec;


#define ngx_time()           ngx_cached_time->sec
#define ngx_timeofday()      (ngx_time_t *) ngx_cached_time
void ngx_time_update(void);

分析:

1.ngx_cached_time 

为了节约资源,避免频繁的系统调用, Nginx 内部使用了比较巧妙的 cache 机制来存放时间
cache机制:

Cache的工作原理是基于程序访问的局部性(通俗说就是把经常用到的数据放在一个高速的cache里面)。

Cache存储器:电脑中为高速缓冲存储器,是位于CPU和主存储器DRAM(Dynamic Random Access Memory)之间,规模较小,但速度很高的存储器,通常由SRAM(Static Random Access Memory静态存储器)组成。 

Cache的功能是提高CPU数据输入输出的速率。

Cache容量小但速度快,内存速度较低但容量大,通过优化调度算法,系统的性能会大大改善,仿佛其存储系统容量与内存相当而访问速度近似Cache。

2.基于 ngx_cached_time,Nginx还定义了另外一个全局变量ngx_current_msec,表示自epoch 以来的毫秒数,即sec * 1000 + msec:(运行时间)
 

3. 两个函 数宏 ng x_t ime ()和 ngx _ timeofday ()可以分别获取当前时间的秒数 (时间戳)
和完整 的时间数据结构
4.void ngx_time_update(void); 
由于 ngx_cached_time 个缓存的时间,可能存在延迟,有时我们必须要获取当前
的精确 时间,这个时候可以调用 ngx time update ()强制更新缓存,然后再 获取时间!!!

2.源码分析 --日期

2.1基本数据结构

#define ngx_tm_sec            tm_sec
#define ngx_tm_min            tm_min
#define ngx_tm_hour           tm_hour
#define ngx_tm_mday           tm_mday
#define ngx_tm_mon            tm_mon
#define ngx_tm_year           tm_year
#define ngx_tm_wday           tm_wday
#define ngx_tm_isdst          tm_isdst

#define ngx_tm_sec_t          int
#define ngx_tm_min_t          int
#define ngx_tm_hour_t         int
#define ngx_tm_mday_t         int
#define ngx_tm_mon_t          int
#define ngx_tm_year_t         int
#define ngx_tm_wday_t         int

1.ngx_tm_t 实际上是一个简单 typedef ,它是标准C结构tm 的同义词

2.tm_isdst :夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的时候,tm_isdst为0;不了解情况时,tm_isdst()为负。

2.2操作函数

void
ngx_localtime(time_t s, ngx_tm_t *tm)
{
#if (NGX_HAVE_LOCALTIME_R)
    (void) localtime_r(&s, tm);

#else
    ngx_tm_t  *t;

    t = localtime(&s);
    *tm = *t;

#endif

    tm->ngx_tm_mon++;
    tm->ngx_tm_year += 1900;
}

ngx_libc_gmtime(time_t s, struct tm *tm)
{
#if (NGX_HAVE_LOCALTIME_R)
    (void) gmtime_r(&s, tm);

#else
    struct tm  *t;

    t = gmtime(&s);
    *tm = *t;

#endif
}
               
void ngx_localtime(time_t s, ngx_tm_t *tm)和ngx_libc_gmtime(time_t s, struct tm *tm)
分别转换为格林尼治标准时间(GMT)
u_char *ngx_http_time(u_char *buf, time_t t);
u_char *
ngx_http_time(u_char *buf, time_t t)
{
    ngx_tm_t  tm;

    ngx_gmtime(t, &tm);

    return ngx_sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d GMT",
                       week[tm.ngx_tm_wday],
                       tm.ngx_tm_mday,
                       months[tm.ngx_tm_mon - 1],
                       tm.ngx_tm_year,
                       tm.ngx_tm_hour,
                       tm.ngx_tm_min,
                       tm.ngx_tm_sec);
}


u_char *ngx_http_cookie_time(u_char *buf, time_t t);

ngx_http_cookie_time(u_char *buf, time_t t)
{
    ngx_tm_t  tm;

    ngx_gmtime(t, &tm);

    /*
     * Netscape 3.x does not understand 4-digit years at all and
     * 2-digit years more than "37"
     */

    return ngx_sprintf(buf,
                       (tm.ngx_tm_year > 2037) ?
                                         "%s, %02d-%s-%d %02d:%02d:%02d GMT":
                                         "%s, %02d-%s-%02d %02d:%02d:%02d GMT",
                       week[tm.ngx_tm_wday],
                       tm.ngx_tm_mday,
                       months[tm.ngx_tm_mon - 1],
                       (tm.ngx_tm_year > 2037) ? tm.ngx_tm_year:
                                                 tm.ngx_tm_year % 100,
                       tm.ngx_tm_hour,
                       tm.ngx_tm_min,
                       tm.ngx_tm_sec);
}

时间格式

extern volatile ngx_str_t    ngx_cached_err_log_time;
extern volatile ngx_str_t    ngx_cached_http_time;
extern volatile ngx_str_t    ngx_cached_http_log_time;
extern volatile ngx_str_t    ngx_cached_http_log_iso8601;
extern volatile ngx_str_t    ngx_cached_syslog_time;

从上到下:

错误日志的日期字符串

HTTP 格式的日期字符串

HTTP 日志的日期
i S08601 格式的日期字 符串
系统日志格式的日期字 符串

3.源码分析--日志

3.1数据结构

struct ngx_log_s {
    ngx_uint_t           log_level;
    ngx_open_file_t     *file;

    ngx_atomic_uint_t    connection;

    time_t               disk_full_time;

    ngx_log_handler_pt   handler;
    void                *data;

    ngx_log_writer_pt    writer;
    void                *wdata;

    /*
     * we declare "action" as "char *" because the actions are usually
     * the static strings and in the "u_char *" case we have to override
     * their types all the time
     */

    char                *action;

    ngx_log_t           *next;
};

针对服务器http/TCP而言

我们只需要了解

1. ngx_uint_t           log_level;     日志级别

2.  ngx_log_t           *next;        日志对象链表指针

3.2操作函数

void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
    const char *fmt, ...);
ngx_log_error_core ()使用ngx_log_t对象记录level 级别的日志,字符串消息的格式语法与ngx_sprintf()相同。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值