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


    1.源码分析-时间

    1.1基本数据结构

    1. typedef struct {
    2. time_t sec;
    3. ngx_uint_t msec;
    4. ngx_int_t gmtoff;
    5. } ngx_time_t;

    结构成员分析:

    ngx_time_t在Nginx里用来表示时间,

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

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

    1.2操作函数

    1. extern volatile ngx_time_t *ngx_cached_time;
    2. extern volatile ngx_msec_t ngx_current_msec;
    3. #define ngx_time() ngx_cached_time->sec
    4. #define ngx_timeofday() (ngx_time_t *) ngx_cached_time
    5. 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基本数据结构

    1. #define ngx_tm_sec tm_sec
    2. #define ngx_tm_min tm_min
    3. #define ngx_tm_hour tm_hour
    4. #define ngx_tm_mday tm_mday
    5. #define ngx_tm_mon tm_mon
    6. #define ngx_tm_year tm_year
    7. #define ngx_tm_wday tm_wday
    8. #define ngx_tm_isdst tm_isdst
    9. #define ngx_tm_sec_t int
    10. #define ngx_tm_min_t int
    11. #define ngx_tm_hour_t int
    12. #define ngx_tm_mday_t int
    13. #define ngx_tm_mon_t int
    14. #define ngx_tm_year_t int
    15. #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操作函数

    1. void
    2. ngx_localtime(time_t s, ngx_tm_t *tm)
    3. {
    4. #if (NGX_HAVE_LOCALTIME_R)
    5. (void) localtime_r(&s, tm);
    6. #else
    7. ngx_tm_t *t;
    8. t = localtime(&s);
    9. *tm = *t;
    10. #endif
    11. tm->ngx_tm_mon++;
    12. tm->ngx_tm_year += 1900;
    13. }
    14. ngx_libc_gmtime(time_t s, struct tm *tm)
    15. {
    16. #if (NGX_HAVE_LOCALTIME_R)
    17. (void) gmtime_r(&s, tm);
    18. #else
    19. struct tm *t;
    20. t = gmtime(&s);
    21. *tm = *t;
    22. #endif
    23. }
    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);
    1. u_char *
    2. ngx_http_time(u_char *buf, time_t t)
    3. {
    4. ngx_tm_t tm;
    5. ngx_gmtime(t, &tm);
    6. return ngx_sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d GMT",
    7. week[tm.ngx_tm_wday],
    8. tm.ngx_tm_mday,
    9. months[tm.ngx_tm_mon - 1],
    10. tm.ngx_tm_year,
    11. tm.ngx_tm_hour,
    12. tm.ngx_tm_min,
    13. tm.ngx_tm_sec);
    14. }


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

    1. ngx_http_cookie_time(u_char *buf, time_t t)
    2. {
    3. ngx_tm_t tm;
    4. ngx_gmtime(t, &tm);
    5. /*
    6. * Netscape 3.x does not understand 4-digit years at all and
    7. * 2-digit years more than "37"
    8. */
    9. return ngx_sprintf(buf,
    10. (tm.ngx_tm_year > 2037) ?
    11. "%s, %02d-%s-%d %02d:%02d:%02d GMT":
    12. "%s, %02d-%s-%02d %02d:%02d:%02d GMT",
    13. week[tm.ngx_tm_wday],
    14. tm.ngx_tm_mday,
    15. months[tm.ngx_tm_mon - 1],
    16. (tm.ngx_tm_year > 2037) ? tm.ngx_tm_year:
    17. tm.ngx_tm_year % 100,
    18. tm.ngx_tm_hour,
    19. tm.ngx_tm_min,
    20. tm.ngx_tm_sec);
    21. }

    时间格式

    1. extern volatile ngx_str_t ngx_cached_err_log_time;
    2. extern volatile ngx_str_t ngx_cached_http_time;
    3. extern volatile ngx_str_t ngx_cached_http_log_time;
    4. extern volatile ngx_str_t ngx_cached_http_log_iso8601;
    5. extern volatile ngx_str_t ngx_cached_syslog_time;

    从上到下:

    错误日志的日期字符串

    HTTP 格式的日期字符串

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

    3.源码分析--日志

    3.1数据结构

    1. struct ngx_log_s {
    2. ngx_uint_t log_level;
    3. ngx_open_file_t *file;
    4. ngx_atomic_uint_t connection;
    5. time_t disk_full_time;
    6. ngx_log_handler_pt handler;
    7. void *data;
    8. ngx_log_writer_pt writer;
    9. void *wdata;
    10. /*
    11. * we declare "action" as "char *" because the actions are usually
    12. * the static strings and in the "u_char *" case we have to override
    13. * their types all the time
    14. */
    15. char *action;
    16. ngx_log_t *next;
    17. };

    针对服务器http/TCP而言

    我们只需要了解

    1. ngx_uint_t           log_level;     日志级别

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

    3.2操作函数

    1. void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
    2. const char *fmt, ...);
    ngx_log_error_core ()使用ngx_log_t对象记录level 级别的日志,字符串消息的格式语法与ngx_sprintf()相同。
  • 相关阅读:
    TL-ER3220G端口映射设置
    《数据库原理与应用》第一版 马春梅……编著 期末复习笔记
    【LeetCode-简单题】383. 赎金信
    在windows10上怎么安装Kafka
    自建工单(审批流)系统设计
    基于stm32单片机的电压报警系统Proteus仿真
    存量时代的面经
    力扣45. 跳跃游戏 II
    yocto(七)——添加layer、添加内核模块、修改源码、制作补丁
    deepwalk&node2vec 代码实战
  • 原文地址:https://blog.csdn.net/qq_62309585/article/details/127962637