Linux原生日志系统Rsyslog详解

article/2025/10/5 21:45:08

一、概述

Rsyslog 是一个 syslogd 的多线程增强版,依然基于Syslog协议(linux6之前默认使用syslog程序,centos6用rsyslog所取代)完成系统日志的处理转发,官方形容它是一个极速(如火箭般快速)的日志处理系统。它提供高性能、极好的安全功能和模块化设计。虽然它基于常规的 syslogd,但 rsyslog 已经演变成了一个强大的工具,可用于:

1)接收来自各种来源的输入

2)转换过滤格式化输出

3)将结果输出到不同的目的地,集成日志分析平台

Rsyslog支持 MySQL、PostgreSQL、故障转移日志目标、ElasticSearch、syslog/tcp 传输、细粒度输出格式控制、高精度时间戳、排队操作以及过滤任何消息部分的能力。它定位于企业级但也考虑了中小系统的需求。RSYSLOG 每秒可以向本地目的地(rsyslogd)传送超过一百万条消息。对远程目的地或需更精细的消息处理时,性能通常也被认为是“惊人的”。目前官方显示最新的稳定版为rsyslog 8.2104.0。

单击查看帮助文档。

Rsyslog是多线程的,是一个基于 TCP、SSL、TLS 和 RELP 的可靠系统日志系统,可以过滤处理系统日志消息的任何内容,支持按需磁盘缓冲,完全可自主配置消息输出格式(包括高-精确时间戳),可写入各种数据库(MySQL、PostgreSQL、Oracle 等),支持电子邮件警报和在线消息压缩以及将文本文件转换为系统日志的能力,它是库存 syslogd 的直接替代品,能够使用相同的配置文件语法。可完全作为企业级中继链应用于日志各种场景中。
在这里插入图片描述
而日志收集和分析在日常的系统管理过程中是很重要的,所有的系统信息都保存在日志文件中,如何快速的查找日志并定位问题所在从而更高效解决问题已是每个运维人员的必备技能。

二、架构

在这里插入图片描述
在这里插入图片描述
从上图中可以看到,日志产生后,先经过预处理器然后就被压入main message queue等待后续的处理,在进入action queue之前,日志被解析器和过滤器处理,它们的作用是读取rsyslog.conf配置文件中设置的规则,和日志中的内容进行对比,然后发送到合适的action queue,一旦日志进入到这个action queue之后,就会从主消息队列中删除。

日志真正被处理的阶段发生在进入action queue之后,action processor(动作处理器)会从action queue中获取最先进入队列的日志进行处理,根据规则进行日志的输出,例如写入文件,录入数据库、发送到远程服务器,甚至是把它们丢弃。

rsyslog.conf中每一条规则的action都有一个action queue,这种queue默认类型是direct queue,但严格来说,它不属于队列,虽然名字中有queue字样。direct queue通常处理简单的行为,例如把日志写入本地文件。

在direct queue下,同一条日志如果被多个动作处理器消费,这个时候,同一条日志会被复制到各个动作队列中,那么可能会造成的现象是,当你使用discard丢弃日志的时候,会发现discard指令没有生效,原因是:discard指令丢弃的是原始日志的副本,而原始的日志会继续活动在原来的工作流中。

其中:

1)早期的sysylog(也就是centos5中使用的)只有2个子进程:
Syslogd ----- 记录系统进程相关的信息
Klogd ----- 记录内核事件相关的信息

2)Rsyslog:

我们可将 rsyslog 视为一个大型日志记录和事件处理工具集。也可认为它是一个具有一些消息处理的框架,限定了数据流动的方式,但消息流的细节又是可高度可定制的。rsyslog的消息流是从输入模块->预处理模块->主队列->消息处理引擎->执行队列(这里有预先定义的规则集ruleset,当规则匹配时,消息会被执行相应的一个动作,对消息进行处理,例如将其写入文件、数据库或转发到远程主机,默认的规则集为RSYSLOG_DefaultRulese)->输出模块。

输入模块有:imklg、imsock、imfile;

输出模块有:omudp、omtcp、omfile、omprog、ommysql、omruleset

rsyslog引入了facility(设施)的概念,也就是 rsyslog服务进程所要接收日志的各代理,这些代理负责收集对应的日志信息,报给rsyslog;常用的日志设施有如下几种:
在这里插入图片描述
上述这些代理/模块可以使用通配符来表示,facility与priority之间用点号隔开; 其中:

代理名称.* // 代表所有,多个dialing之间可用分号分隔;前面加!表取反

在这里插入图片描述
另外系统日志还有priority优先级概念,优先级分别为:

debug info notice warn err crit alert emerg
在这里插入图片描述
优先级中也可以使用通配符

优先级.* //表示所有,不同优先级之间要用分号;隔开
优先级.None //表示不记录

在这里插入图片描述
执行:top -H -p rsyslogd_PID //查看rsyslog的线程

在这里插入图片描述
执行:rsyslogd -ver //查看 rsyslog 版本
在这里插入图片描述
centos5系列系统自带为syslog1.4.1;centos6系列自带rsyslog版本为5.8.10;centos7系列自带rsyslog版本为7.4.7。rsyslog v5 已经过时了,它的原生配置语言很痛苦。 rsyslog 项目强烈建议至少使用第 7 版。目前最新版rsyslog为8.27.0,rsyslog从8.5.0后对imfile模块进行重构,文件名中可以支持通配符。

2.1、rsyslog 组价特性

1)属性替代

Rsyslog预定义了一些属性,来代表消息中的信息(即元消息),我们可以在定义输出格式、动态文件名的时候使用到这些属性。这里面比较重要的属性有:msg(消息体)、hostname、pri(消息等级和类别)、time(时间有关),属性的名称中以$开头的是从本地系统获得的变量、不带$是从消息中获得变量。

属性替代的语法格式:%propname:fromChar:toChar:options:fieldname%

我们可以使用起始字符获取自己所需的字段,也可以使用正则表达式,也可以使用分隔符。比如:为了兼容一个rfc协议,rsyslog规定如果用户输入的msg不是以空格开头,rsyslog会自动补充一个空格,因此如果你希望输出的时候去掉这个空格,就可以使用以下这种格式:

%msg:2:$% //选取msg变量中,起始位置为2,终止位置为结尾

如想要根据空格来拆分字符串,F表示使用字符分割,32是空格的ascii码,可这样配置:

%msg:F,32:3% //按照空格分隔,取第三个子串

属性替代中还用到了一类特殊的以 $!开头的变量,这是使用mmnormalize模块时特有的,可以实现类似于syslog-ng中parser模块的功能。

2)模板

模板的功能是定义输出格式,或者定义omfile模块的动态路径、动态文件。

模板定义的形式有四种,适用于不同的输出模块,一般简单的格式,可以使用string的形式,复杂的格式,建议使用list的形式,使用list的形式,可以使用一些额外的属性字段(property statement),例如:position.from、position.end。如果不指定输出模板,rsyslog会默认使RSYSLOG_DEFAULT。

如果你只想输出msg,可以定义模板:
$template t_msg, “%msg\n%” //
如果想按日期保存输出,需要使用动态路径。可以定义模板
$template f_debug, “/data0/logs/%$year%-%$month%-%$day%/debug.log”

3)Ruleset

Ruleset实现的是多实例的功能,可以针对syslog的来源使用不同的过滤规则。需要注意的是,在配置文件中需要先定义ruleset,才可以使用。比较典型的一个例子,针对不同的端口使用不同的过滤规则。示例如下:
$Ruleset tcp1999 $RulesetCreateMainQueue on Local3.* @@10.0.0.44:1999 $Ruleset tcp2000 $RulesetCreateMainQueue on Local4.* @@10.0.0.44:2000

在定义好ruleset后,各个输出模块就可以指定自己使用的ruleset了,具体如何指定,可以查看输出模块的手册,可单击查看。

4)Filter模块

Rsyslog可以使用syslog标准的过滤规则,同时自己添加了一些扩展。比如可以在输出中指定rsyslog自己的处理方式,可以指定输出template,方法是在规则后面添加template的名字,用分号隔开。

例如我们可以编写一个规则:

Local3.* -/data0/logs/local3.log;t_msg #在这个输出中使用t_msg的模板 
Local4.* -?f_local3_test;t_msg #问号表示要使用模板定义的动态路径

除了syslog标准的规则,rsyslog的作者还自己开发了一个叫做rainerscript的脚本语言,来定义更复杂的过滤过则,rainerscript可以对属性进行startwith、contains、%(取余)等过滤规则,例如:

If $pri-txt == local3.* and $msg contains “abc” then{ #pri为local3,且在消息中包含子串‘abc’ 
*.* -/data0/logs/local3.log;t_msg }

还有第三种方式是使用属性的表示方式,例如:

: msg, regex, "^ [g-z]" /root/rsyslog_worker_dir/2000.log #以字母g到z开头的消息,注意msg开头有个空格

5)队列

队列是rsyslog中比较重要的一个部分,作为使用者,我们需要了解的是队列的种类:主队列(main message queue)工作队列(action queue)
在这里插入图片描述

从输入模块接收的消息会进入主队列,主队列中的消息,经过过滤模块,会进入到相应的工作队列;队列的四种工作模式:direct mode、disk mode、FixedArray mode和LinkedList mode,前两种是磁盘队列,更可靠,但是性能也较差,后两种是内存队列,区别是前者是预分配队列长度,后者是动态分配,如果你的系统日志流量比较平稳,可以使用预分配队列,如果日志属于突发型,可以使用动态队列。此外,内存队列还可以通过指定一个queuename来添加DA模式,DA模式主要是为了防止意外情况(进程关闭、server端宕机)下,内存队列可以不丢失。
在这里插入图片描述

rsyslog中只有一个主消息队列,任何消息都要先进入这个队列,然后直到进入到动作队列之后消息才会从这个队列中删除。通常,我们都不会太过在意主消息队列的设置,因为默认的设置已经工作得很好;往往rsyslog中的关于队列的配置,都是针对动作队列的。消息经过主消息队列之后,就被rule processor解析和处理,然后根据预先配置的规则压入各自的动作队列,动作队列之后消息最终被消费掉,例如输出到指定的地方。正是如此,往往我们都会根据实际情况对动作队列的行为作出一些适当的调整。

设置队列类型的语法如下:

$<Object>QueueType  <QueueTypeValue>  #Object可以代表MainMsg或Action

通过查看rsyslog的系统命令,可以知道rsyslog对队列进行大量的可配参数,来定义队列的行为。可以根据需要来进行优化。关于队列更多,请参看。

注意:

如果消息最终不能被消费(输出到指定位置),那么这些消息就会停留在先前的队列中。这就有可能会导致队列被填满,一旦队列填满,后续的输入消息就不能再进入消息队列,最终造成某些服务无法进行日志记录,最坏的后果是导致该服务无法正常提供服务。比如某次故障时, CPU/Disk/Mem 都正常, 但某些进程异常卡顿, 排查2天, 竟然发现是 rsyslog 的锅: 因为 ES 挂了, rsyslog-elasticsearch 队列被打满且阻塞, 然而 rsyslog 默认主队列是 direct, 也就是必须等待elasticsearch子列队超时才返回, 导致 sshd, sudo , rsync , php.syslog等凡是用到 syslog 的地方被阻塞, 后果很严重!!! 所以合理配置主队列和动作队列的类型及丢弃策略非常必要!!!

三、配置详解

配置文件:/etc/rsyslog.conf, /etc/rsyslog.d/,对于不使用默认配置文件的,可在命令行使用-f 来指定rsyslog服务启动所要的配置文件。rsyslogd从 rsyslog.conf 的顶部到底部进行指令处理。因此配置文件中的语句顺序很重要。例如,如果停止处理某一条消息,则停止语句之后的所有语句都不会被读取应用。配置文件修改完成后,可执行以下命令测试配置文件:

rsyslogd -N1 -f file

​主程序:/usr/sbin/rsyslogd

1)正常启动:rsyslogd -f /root/rsyslog_worker_dir/rsyslog.conf -i /root/rsyslog_worker_dir/rsyslog.pid

2)Debug方式:

rsyslogd -f /root/rsyslog_worker_dir/rsyslog.conf -i /root/rsyslog_worker_dir/rsyslog.pid -dn >debuglog

​模块路径:/usr/lib64/rsyslog/

Unit File:/usr/lib/systemd/system/rsyslog.service

3.1、Rsyslog配置文件

配置文件由三部分组成:严格按照配置段位置添加配置

MODULES

GLOBAL DIRECTIVES

RULES

可通过以下命令确认:grep “####” /etc/rsyslog.conf
在这里插入图片描述
其中:
MODULES:定义了模块的选修,如接下来的使用mysql模块记录日志则需要在这里配置

GLOBAL DIRECTIVES:定义了全局的环境

RULES:定义了记录日志的设施以及等级等信息

1)文件格式:

日志定义格式: facility.priority    Targetfacility: 设施,从功能或程序上对日志进行分类,并由专门的工具负责记录日志;常用的facility:lpr: 打印相关的日志auth:认证相关的日志,pam产生的日志user:用户相关的日志cron:计划任务相关的日志kern:内核相关的日志mail:邮件相关的日志mark:标记相关的日志,rsyslog服务内部的信息,时间标识news:新闻相关的日志uucp:文件copy相关的日志,unix to unix copy, unix主机之间相关的通讯daemon:系统服务相关的日志authpriv: 授权相关的日志,ssh,ftp等登录信息的验证信息security:安全相关的日志local0-local7:自定义相关的日志信息(自定义时可以使用通配符)通配符:*:所有f1,f2,f3......:列表!:取反priority:指定日志级别,常用的日志级别,从上到下,级别从低到高,记录的信息越来越少:debug:   调试info:   消息notice: 注意warn,warning: 警告err,error: 错误crit: 严重级别alert: 需要立即修改该的信息emerg,panic: 内核崩溃,内核恐慌等严重的信息none:       什么都不记录通配符:*:所有日志级别none:没有任何级别,也就是不记录日志信息Target:文件路径可以使用的有:/var/log/messages用户:*  当前登录系统的所有用户日志服务器:@SERAVER_IP管道:| COMMAND

配置文件内容查看:cat /etc/rsyslog.conf|grep -vE “#|$” > ./rsyslog.conf.def //去掉注释和空行后

$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
$WorkDirectory /var/lib/rsyslog
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$IncludeConfig /etc/rsyslog.d/*.conf
$OmitLocalLogging on
$IMJournalStateFile imjournal.state
*.info;mail.none;authpriv.none;cron.none                /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 :omusrmsg:*
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.logauthpriv.info /var/log/authpriv.logkern.warning /var/log/kern.log*.err /var/log/errors.logauth.none /var/log/auth.log
*.err;kern.debug;daemon.notice /var/adm/messages

2)日志规则定义示例:

mail.info  /var/log/maillog		# 比指定级别更高的日志级别,包括指定级别自身,保存到/var/log/maillog中
mail.=info  /var/log/maillog	# 明确指定日志级别为info,保存至/var/log/maillog
mail.!info  /var/log/maillog	# 除了指定的日志级别(info)所有日志级别信息,保存至/var/log/maillog
*.info      /var/log/maillog	# 所有facility的info级别,保存至/var/log/maillog
mail.*     /var/log/maillog	    #mail的所有日志级别信息,都保存至/var/log/maillog
mail.notice;news.info  /var/log/maillog	 #mail的notice以上的日志级别和news的info以上的级别保存至/var/log/maillog
mail,news.crit  -/var/log/maillog	#mail和news的crit以上的日志级别保存/var/log/maillog中;“-”代表异步模式
*.*     /var/log/file.log   # 绝对路径;记录到普通文件或设备文件
*.*     /dev/pts/0
*.* @192.168.0.1            # 使用UDP协议转发到192.168.0.1的514(默认)端口
*.* @@192.168.0.1:10514     # 使用TCP协议转发到192.168.0.1的10514(默认)端口
*.*   root,kadefor,up01     # 使用,号分隔多个用户,发送给用户(需要在线才能收到)
local3.*   ~    			# 忽略所有local3类型的所有级别的日志
local3.*    ^/tmp/a.sh      # ^号后跟可执行脚本或程序的绝对路径

3)rsyslog.conf完全配置内容

#rsyslog v3 config file# if you experience problems, check# http://www.rsyslog.com/troubleshoot for assistance#### MODULES ####    加载 模块$ModLoad imuxsock.so  –> 模块名    # provides support for local system logging (e.g. via logger command) 本地系统日志$ModLoad imklog.so                    # provides kernel logging support (previously done by rklogd)#$ModLoad immark.so              # provides –MARK– message capability# Provides UDP syslog reception# 允许514端口接收使用UDP协议转发过来的日志#$ModLoad imudp.so#$UDPServerRun 514   # Provides TCP syslog reception# 允许514端口接收使用TCP协议转发过来的日志#$ModLoad imtcp.so#$InputTCPServerRun 514#### GLOBAL DIRECTIVES ####定义日志格式默认模板  # Use default timestamp format$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat  # File syncing capability is disabled by default. This feature is usually not required,# not useful and an extreme performance hit#$ActionFileEnableSync on#### RULES ##### Log all kernel messages to the console.# Logging much else clutters up the screen.#kern.*                                                 /dev/console    关于内核的所有日志都放到/dev/console(控制台)# Log anything (except mail) of level info or higher.# Don’t log private authentication messages!# 记录所有日志类型的info级别以及大于info级别的信息到/var/log/messages,但是mail邮件信息,authpriv验证方面的信息和cron时间任务相关的信息除外*.info;mail.none;authpriv.none;cron.none                /var/log/messages  # The authpriv file has restricted access.# authpriv验证相关的所有信息存放在/var/log/secureauthpriv.*                                              /var/log/secure  # Log all the mail messages in one place.# 邮件的所有信息存放在/var/log/maillog; 这里有一个-符号, 表示是使用异步的方式记录, 因为日志一般会比较大mail.*                                                  -/var/log/maillog  # Log cron stuff# 计划任务有关的信息存放在/var/log/croncron.*                                                  /var/log/cron  # Everybody gets emergency messages# 记录所有的大于等于emerg级别信息, 以wall方式发送给每个登录到系统的人*.emerg                                                 *                  *代表所有在线用户  # Save news errors of level crit and higher in a special file.# 记录uucp,news.crit等存放在/var/log/spooleruucp,news.crit                                          /var/log/spooler  # Save boot messages also to boot.log     启动的相关信息local7.*                                                /var/log/boot.log#:rawmsg, contains, “sdns_log” @@192.168.56.7:10514#:rawmsg, contains, “sdns_log” ~# ### begin forwarding rule ###  转发规则# The statement between the begin … end define a SINGLE forwarding# rule. They belong together, do NOT split them. If you create multiple# forwarding rules, duplicate the whole block!# Remote Logging (we use TCP for reliable delivery)## An on-disk queue is created for this action. If the remote host is# down, messages are spooled to disk and sent when it is up again.#$WorkDirectory /var/spppl/rsyslog # where to place spool files#$ActionQueueFileName fwdRule1 # unique name prefix for spool files#$ActionQueueMaxDiskSpace 1g   # 1gb space limit (use as much as possible)#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown#$ActionQueueType LinkedList   # run asynchronously#$ActionResumeRetryCount -1    # infinite retries if host is down# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional#*.* @@remote-host:514                    # @@表示通过tcp协议发送    @表示通过udp进行转发#local3.info  @@localhost:514#local7.*                                    #            @@192.168.56.7:514# ### end of the forwarding rule ###

3.2、配置示例

1)过滤特定的日志到文件, 忽略(丢弃)包含某个字符串的日志,过滤日志, 由:号开头

:msg, contains, “error” /var/log/error.log
:msg, contains, “error” ~         # 忽略包含error的日志
:msg, contains, “user nagios”   ~
:msg, contains, “user kadefor”   ~
:msg, contains, “module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write” ~
local3.*    ~
PS.
&   ~       # 忽略所有的日志

2)使用模板来定义日志格式,按默认的日志格式定义:

$template myFormat,”%rawmsg%\n”  $ActionFileDefaultTemplate myFormat  #如果不要$ActionFileDefaultTemplate myFormat这一行, 就需要像这样来使用模板:#在日志文件后添加模板名, 并用;号分隔$template myFormat,”%rawmsg%\n”  # The authpriv file has restricted access.authpriv.*      /var/log/secure;myFormat  # Log all the mail messages in one place.mail.*          /var/log/maillog;myFormat  # Log cron stuffcron.*          /var/log/cron;myFormat  # Everybody gets emergency messages*.emerg                                       *  # Save news errors of level crit and higher in a special file.uucp,news.crit  /var/log/spooler;myFormat  # Save boot messages also to boot.loglocal7.*        /var/log/boot.log;myFormat 

3)rsyslog服务端配置
vi /etc/rsyslog.conf

$ModLoad imtcp.so           # needs to be done just once #使用tcp方式
$InputTCPMaxSessions 500    # tcp接收连接数为500个
$InputTCPServerRun 514      # tcp接收信息的端口
$template logformat,”%TIMESTAMP:::date-mysql% %FROMHOST-IP%%msg%\n”     # 定义一个名为logformat模板, 为信息加上日志时间
$template DynFile,”/var/log/tlog%$year%%$month%%$day%.log”     # 定义日志文件的名称,按照年月日
:rawmsg, contains, “sdns_log” ?DynFile;logformat    # 把rawmsg(也可以使用msg)日志中包含sdns_log标志的信息写到DynFile定义的日志文件里
:rawmsg, contains, “sdns_log”  ~                     # 这个表示丢弃包含sdns_log标志的信息, 一般都加上它, 以免多个日志文件记录重复的日志
#把不同服务器发送过来的日志保存到不同的文件
:fromhost-ip, isequal, “192.168.0.160″ /var/log/host160.log
:FROMHOST-IP, isequal, “192.168.0.161″ /var/log/host161.log
:FROMHOST-IP, startswith, “192.168.1.” /var/log/network1.log
:FROMHOST-IP, startswith, “192.168.2.” /var/log/network2.log

4)客户端配置

#把包含sdns_log的信息通过tcp发到192.168.1.2 @@表示tcp @表示udp
:rawmsg, contains, “sdns_log”       @@192.168.1.2       # 默认514端口
#这个 ~ 表示丢弃包含sdns_log标志的信息,防止这个信息写到本机的/var/log/message
:rawmsg, contains, “sdns_log”       ~

5)将客户端执行的所有命令写入系统日志/var/log/messages 中

vi /etc/bashrc

export PROMPT_COMMAND={ msg=$(history 1 | { read x y; echo $y; });logger “[euid=$(whoami)]”:$(who am i):[pwd]$msg; }# 在结尾处加上此内容

source /etc/bashrc

3.3、常见日志:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、关联版本

4.1、Syslog-ng

syslog-ng应用程序是一个灵活和高度可伸缩的系统日志应用程序,是创建集中的和可信的日志解决方案的理想选择。syslog-ng的主要特征概括如下:

(1)可靠的日志传输:syslog-ng应用程序能够发送你的主机到远程服务器的日志消息使用最新的协议标准。不同服务器的日志可以收集并存储在专用的日志服务器上集中。将日志消息使用TCP协议确保不会有消息丢失。

(2)使用TLS安全日志: 日志消息可能包含敏感信息,不应由第三方访问。因此,syslog-ng支持传输层安全(TLS)协议加密通信。TLS也允许宿主的相互的身份验证,并使用X.509证书。

(3)直接数据库访问: 存储数据库中的日志消息使您可以轻松地搜索和查询日志分析的信息和互操作的应用程序。

syslog-ng应用程序支持以下数据库:MSSQL,MySQL,ORACLE,PostgreSQL,SQLite

(4)不同平台支持: syslog-ng应用程序的理想选择收集日志在大规模异构环境中使用不同的操作系统和硬件平台,包括Linux、Unix、BSD、Sun Solaris,hp-ux,Tru64,AIX。

(5)过滤和分类: syslog-ng应用程序可以传入日志消息根据其内容和各种参数,像源主机应用程序,和优先级。目录、文件和数据库表可以创建动态使用宏。

复杂的过滤使用正则表达式和布尔操作符提供了几乎无限的灵活性,只有重要的日志消息转发给所选择的目的.

(6)解析和重写: syslog-ng应用程序可以段日志消息命名字段或列,并修改这些字段的值。

(7)IPv4和IPv6支持:syslog-ng应用程序可以运行在两个IPv4和IPv6网络环境;它可以接收和发送信息到两种类型的网络。

更多详情单击查看:

4.2、 logrotate

rsyslog负责写入日志, logrotate负责备份和删除旧日志, 以及更新日志文件;查看当前系统的logrotate,执行:rpm -qi logrotate
在这里插入图片描述

4.3、logger命令:用于产生日志

logrotate是一个日志管理程序,用来把旧的日志文件删除(备份),并创建新的日志文件,这个过程称为“转储”。我们可以根据日志的大小,或者根据其使用的天数来转储。logrotate 的执行由crond服务实现。在/etc/cron.daily目录中,有个文件logrotate,它实际上是个shell script,用来启动logrotate。logrotate程序每天由cron在指定的时间(/etc/crontab)启动。因此,使用ps是无法查看到logrotate的。如果它没有起来,就要查看一下crond服务有没有在运行。
在这里插入图片描述
在执行logrotate时,需要指定其配置文件/etc/logrotate.conf;如果安装了一个新的服务,它的日志转储的规则可以建立一个专门的配置文件,放在/etc/logrotate.d下面,在 logrotate服务启动时被读取。如果与logrotate.conf中的冲突,以/etc/logrotatate.d/中的文件定义的为准。logrotate启动脚本放在 /etc/cron.daily/logrotate 中,可人工执行命令进行测试:

/usr/sbin/logrotate -f /etc/logrotate.conf //-f强制轮转,-v参数查看轮转的过程
在这里插入图片描述
eg1:logger -t ‘LogTest’ -p local3.info ‘KadeFor is testing the rsyslog and logger’

eg2:logger -p local3.info ‘KadeFor is testing the rsyslog and logger’

vim /etc/logrotate.conf

# see “man logrotate” for details
# rotate log files weekly
weekly          –每周轮转一次
# keep 4 weeks worth of backlogs
rotate 4        –保留四个
# create new (empty) log files after rotating old ones
create          –rotate后,创建一个新的空文件
# uncomment this if you want your log files compressed
#compress       –默认是不压缩的
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d        –这个目录下面配置文件生效
# no packages own wtmp — we’ll rotate them here
/var/log/wtmp {             –定义/var/log/wtmp这个日志文件
monthly                 –每月轮转一次,取代了上面的全局设定的每周轮转一次
minsize 1M              –定义日志必须要大于1M大小才会去轮转
create 0664 root utmp   –新的日志文件的权限,属主,属主
rotate 1                –保留一个,取代了上面的全局设定的保留四个
}
/var/log/btmp {
missingok       –如果日志丢失, 不报错
monthly
create 0600 root utmp
rotate 1
}
::
# sample logrotate configuration file
compress
# 全局设置, 压缩
/var/log/messages {
rotate 5     # 保留5份日志
weekly       # 每周轮换一次
postrotate   # 轮换之后重启syslogd服务
/usr/bin/killall -HUP syslogd
# rhel6中为:/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
# 可查看/etc/logrotate.d/下的配置文件
endscript
}
“/var/log/httpd/access.log” /var/log/httpd/error.log {   #  指定多个文件, 如果有特殊字符需要用单引号
rotate 5
mail www@my.org
size 100k        # 超过100k后切换日志, 并把老的日志发送邮件给www@my.org
sharedscripts    # 共享脚本. 下面的postrotate脚本只运行一次.
postrotate
/usr/bin/killall -HUP httpd
endscript
}
/var/log/news/* {    # 少用通配符, 因会它会包括已经切换过的日志, 要用的话最好在*号后加上扩展名, 如*.log
monthly
rotate 2
olddir /var/log/news/old
missingok
postrotate
kill -HUP ‘cat /var/run/inn.pid‘
endscript
nocompress
}

在这里插入图片描述
vim /etc/logrotate.d/syslog
在这里插入图片描述
其中:
/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron {
sharedscripts –表示切换时脚本只执行一次
postrotate –表示rotate后执行的脚本
/bin/kill -HUP cat /var/run/syslogd.pid 2> /dev/null 2> /dev/null || true
/bin/kill -HUP cat /var/run/rsyslogd.pid 2> /dev/null 2> /dev/null || true
endscript –表示脚本结束
}

4.4、Windows Syslog Server

在这里插入图片描述
官方文档

五、应用实践

1)场景1:
在这里插入图片描述
2)场景2:
在这里插入图片描述
3)场景3:
在这里插入图片描述
在这里插入图片描述

4)场景4:
在这里插入图片描述
5)场景5:
在这里插入图片描述
6)场景6:
在这里插入图片描述
7)场景7:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
8)场景8:安全审计
在这里插入图片描述
9)场景9:
在这里插入图片描述
10)场景10:芒果ELK日志,rsyslog作为日志中转
在这里插入图片描述

单击参看。

11)场景11:
在这里插入图片描述

企业日志架构的4个典型场景
在这里插入图片描述
在这里插入图片描述
【kafka辅助优势】

(1).解决了前后端耦合的问题,后端服务出现问题时不会对前端服务造成影响。

(2).有很好的可扩展性,Kafka天生就支持分布式,写入和消费都可以很好的进行扩展,解决了LVS的各种网络限制,可以任意加入队列节点进行扩展。

(3).良好的数据安全性支持,Kafka本身具有副本的概念,可以进行数据备份,在Kafka自身单个节点出现问题时有很好的副本机制,保证了数据的安全性。

(4).Kafka由于使用磁盘作为主要存储介质,相比于Redis队列,可以节省很多的内存资源。从手机微博的使用的情况来看,Kafka单机的处理能力基本上是可以把双千兆网卡跑满。

(5).支持多消费者消费,一次写入,多个业务方可以同时消费数据,并彼此不干扰。

那么引入Kafka的日志传输架构是不是就十全十美了呢?其实也并不是,我简单说说我们目前使用Kafka作为队列时遇到的一些问题。

【缺 点】

我们现在日志收集端使用的是Rsyslog(当然fileBeats也存在这个问题),Rsyslog本身的配置要求只能允许配置一组Kafka,如果出现后端kafka整体不可用时,目前只能采用替换日志服务配置的方式进行服务切换。如果在服务器数量较少时还好说,但是对于像微博这样体量的公司的服务器数量来讲,重启一遍服务器还是需要花费一定时间的,这样必然会对服务传输造成影响。同时下游消费方也需要进行数据消费的切换。又会出现上下游的耦合联动。

当然可以考虑通过提高Kafka的副本数,并使用多机房冗余的方式解决此问题,但是这又涉及到成本上成倍增加的问题,所以相关经验实践中,采用了在保证成本尽量少的情况下加入类似代理的方式解决。

另外还要考虑成本的概念,比如在介绍第一种架构时,只有几台应用服务器的个人项目,如果这个时候就引入Kafka,Zookeeper那么对于后期维护来讲就是一个灾难。所以对处于创业阶段或者是快速成长的企业来讲,架构的快速迭代是很好的选择。

而对于已经处在成熟阶段的大厂同学来讲,在进行日志架构设计时,可能需要更多的考虑上下游的业务关系,尽量做到上下游的业务关系透明,彼此隔离,互不影响,尽量做到传输上的点对点分段治理。还要留好可扩展的“后路”。这一点可能只有当你真正在大厂工作一段时间才会深有体会。

网络实例:这是一个手机微博日志系统的例子,当时微博采用的还是前端Rsyslog到LVS,LVS负载均衡到Rsyslog中转解析集群,中转Rsyslog解析后传输到后端的日志系统或其他数据部门,这种日志架构,经常在晚高峰阶段出现前端的日志堆积,那么到底是LVS的问题还是后端Rsyslog中转解析的问题,又或者是后端数据部门的传输拖慢了整个系统?从现象上看都有可能,由于涉及到第三方部门,排查和沟通就非常的繁琐,问题也比较难于定位,更有甚者,后端的数据部门也采用了LVS的负载均衡方式接收数据,那么在后端数据部门来看,还要分析到底是自身的问题,还是LVS的问题,这又牵扯到第三方业务部门。最后往往难于给出一个结论。

另外一个问题是这种架构采用的是推送数据的方式,而我们的中转日志解析的推送服务都部署在同一组Rsyslog日志解析服务集群上,这就会有另外一个问题,如果一个接受方出现问题,往往会对整体的日志解析造成影响,而排查具体是哪一个业务方拖慢了整体的解析服务就变的非常的困难。

对上述问题的改造就是,将日志推送逐渐的迁移到了以Kafka为数据总线的架构上。我们负责将数据直接点对点的写入Kafka的topic里,而下游消费方直接消费自己topic的数据,彼此隔离,同时Kafka可以按照topic进行监控,可以看到后端的消费堆积情况。到底是我写入有问题,还是你消费有问题可以一目了然的看到,彼此服务管理的界限也非常的清楚。

12)场景12:实现日志存储在mysql中

1> 安装rsyslog连接至mysql server的驱动模块:

yum install -y rsyslog-mysql

rpm -ql rsyslog-mysql //输出如下,包含启动mysql的模块还有createDB.sql
/lib64/rsyslog/ommysql.so
/usr/share/doc/rsyslog-mysql-5.8.10
/usr/share/doc/rsyslog-mysql-5.8.10/createDB.sql

2> 在mysql server准备rsyslog专用的用户账号;

mysql>GRANT ALL ON Syslog.* TO 'rsyslog'@'127.0.0.1' IDENTIFIED BY 'rsyslog123';
mysql>GRANT ALL ON Syslog.* TO 'rsyslog'@'local' IDENTIFIED BY 'rsyslog123';
mysql> FLUSH PRICVILEGES

3> 导入rsyslogr日志存储的sql语句到mysql,生成所需要的数据库和表,执行:

mysql -ursyslog -h127.0.0.1 -p123456 < /usr/share/doc/rsyslog-mysql-5.8.10/createDB.sql

mysql> USE Syslog
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> SHOW TABLES;
+------------------------+
| Tables_in_Syslog       |
+------------------------+
| SystemEvents           |
| SystemEventsProperties |
+------------------------+
2 rows in set (0.00 sec)
mysql> DESC SystemEvents-> ;
+--------------------+------------------+------+-----+---------+----------------+
| Field              | Type             | Null | Key | Default | Extra          |
+--------------------+------------------+------+-----+---------+----------------+
| ID                 | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| CustomerID         | bigint(20)       | YES  |     | NULL    |                |
| ReceivedAt         | datetime         | YES  |     | NULL    |                |
| DeviceReportedTime | datetime         | YES  |     | NULL    |                |
| Facility           | smallint(6)      | YES  |     | NULL    |                |
| Priority           | smallint(6)      | YES  |     | NULL    |                |
| FromHost           | varchar(60)      | YES  |     | NULL    |                |
| Message            | text             | YES  |     | NULL    |                |
| NTSeverity         | int(11)          | YES  |     | NULL    |                |
| Importance         | int(11)          | YES  |     | NULL    |                |
| EventSource        | varchar(60)      | YES  |     | NULL    |                |
| EventUser          | varchar(60)      | YES  |     | NULL    |                |
| EventCategory      | int(11)          | YES  |     | NULL    |                |
| EventID            | int(11)          | YES  |     | NULL    |                |
| EventBinaryData    | text             | YES  |     | NULL    |                |
| MaxAvailable       | int(11)          | YES  |     | NULL    |                |
| CurrUsage          | int(11)          | YES  |     | NULL    |                |
| MinUsage           | int(11)          | YES  |     | NULL    |                |
| MaxUsage           | int(11)          | YES  |     | NULL    |                |
| InfoUnitID         | int(11)          | YES  |     | NULL    |                |
| SysLogTag          | varchar(60)      | YES  |     | NULL    |                |
| EventLogType       | varchar(60)      | YES  |     | NULL    |                |
| GenericFileName    | varchar(60)      | YES  |     | NULL    |                |
| SystemID           | int(11)          | YES  |     | NULL    |                |
+--------------------+------------------+------+-----+---------+----------------+
24 rows in set (0.00 sec)

4> 配置rsyslog加载ommysql模块


#### MODULES ####
......
$ModLoad ommysql

5> 配置RULES,将所期望的日志信息记录于mysql中

其格式为:

facility.priority :ommysql:DBHOST,DB,DBUSER,DBUSERPASS

配置文件中添加以下信息:

.
:ommysql:127.0.0.1,Syslog,rsyslog,123456

6> 启动mysql服务,重启rsyslog服务,登录mysql查看已经记录日志,到此为止,日志信息已经成功的存储于数据库中。

mysql> SELECT * FROM SystemEvents\G
*************************** 1. row ***************************ID: 1CustomerID: NULLReceivedAt: 2016-10-16 13:35:46
DeviceReportedTime: 2016-10-16 13:35:46Facility: 0Priority: 6FromHost: centos6Message: imklog 5.8.10, log source = /proc/kmsg started.NTSeverity: NULLImportance: NULLEventSource: NULLEventUser: NULLEventCategory: NULLEventID: NULLEventBinaryData: NULLMaxAvailable: NULLCurrUsage: NULLMinUsage: NULLMaxUsage: NULLInfoUnitID: 1SysLogTag: kernel:EventLogType: NULLGenericFileName: NULLSystemID: NULL
*************************** 2. row ***************************ID: 2CustomerID: NULLReceivedAt: 2016-10-16 13:35:46
DeviceReportedTime: 2016-10-16 13:35:46Facility: 5Priority: 6FromHost: centos6Message:  [origin software="rsyslogd" swVersion="5.8.10" x-pid="3081" x-info="http://www.rsyslog.com"] startNTSeverity: NULLImportance: NULLEventSource: NULLEventUser: NULLEventCategory: NULLEventID: NULLEventBinaryData: NULLMaxAvailable: NULLCurrUsage: NULLMinUsage: NULLMaxUsage: NULLInfoUnitID: 1SysLogTag: rsyslogd:EventLogType: NULLGenericFileName: NULLSystemID: NULL
*************************** 3. row ***************************ID: 3CustomerID: NULLReceivedAt: 2016-10-16 13:35:50
DeviceReportedTime: 2016-10-18 10:48:37Facility: 18Priority: 6FromHost: localhostMessage:  nidhaiNTSeverity: NULLImportance: NULLEventSource: NULLEventUser: NULLEventCategory: NULLEventID: NULLEventBinaryData: NULLMaxAvailable: NULLCurrUsage: NULLMinUsage: NULLMaxUsage: NULLInfoUnitID: 1SysLogTag: root:EventLogType: NULLGenericFileName: NULLSystemID: NULL
*************************** 4. row ***************************ID: 4CustomerID: NULLReceivedAt: 2016-10-16 13:35:52
DeviceReportedTime: 2016-10-18 10:48:39Facility: 18Priority: 6FromHost: localhostMessage:  DNTSeverity: NULLImportance: NULLEventSource: NULLEventUser: NULLEventCategory: NULLEventID: NULLEventBinaryData: NULLMaxAvailable: NULLCurrUsage: NULLMinUsage: NULLMaxUsage: NULLInfoUnitID: 1SysLogTag: root:EventLogType: NULLGenericFileName: NULLSystemID: NULL
4 rows in set (0.00 sec)

7> 使用loganalyzer显示web日志管理页面

yum install -y httpd mysql mysql-server php php-mysql //如果想看统计图表,需要安装php-gd

ss -tunl | grep 80 3306 //确定服务启动
cd /var/www/html/
vim index.php

Hello 51CTO
My Blog is "http://il23f.blog.51cto.com"
<?php
phpinfo();
?>
<?php
$link = mysql_connect('127.0.0.1','root','');if ($link)echo "success";elseecho "failure";
?>

浏览器输入网址验证http和php是否正常
在这里插入图片描述
软件下载:
wget https://download.adiscon.com/loganalyzer/loganalyzer-4.1.12.tar.gz // 2021-04-29
tar zxfloganalyzer-4.1.12.tar.gz
cd loganalyzer-4.1.12/
mkdir -p /var/www/html/loganalyzer
cp -a src/* /var/www/html/loganalyzer/
chmod 666 config.php //修改config.php文件权限为644
在这里插入图片描述
修改rsyslog的配置文件rsyslog.conf,只需开启两个模块以及允许通过tcp,udp发出接受信息,并且设置信息都保存至mysql数据库的Syslog中
在这里插入图片描述
在这里插入图片描述
cd contrib/
cp configure.sh /var/www/html/loganalyzer/
cd /var/www/html/loganalyzer/
sh configure.sh

浏览器访问:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
引用https://blog.51cto.com/il23f/1386463;

13)场景13:关于docker中的使用

参看:Docker 日志管理最佳实践


http://chatgpt.dhexx.cn/article/JEjrDHtS.shtml

相关文章

N皇后问题-回溯法-C语言

关于对N皇后问题和回溯法的理解 个人非常推荐下面这个视频&#xff1a;算法与数据结构&#xff0c;回溯法求解八皇后&#xff0c;最经典的递归问题_哔哩哔哩_bilibili八皇后问题是计算机科学中最为经典的问题之一&#xff0c;该问题由国际西洋棋棋手马克斯贝瑟尔于1848年提出。…

Java——N皇后问题

题目链接 leetcode在线oj题——N皇后 题目描述 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff…

N 皇后问题

n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案&#xff0c;该方案中 Q 和 . 分别代表了皇后和…

N皇后问题(C++)

n−皇后问题是指将 n 个皇后放在 nn 的国际象棋棋盘上&#xff0c;使得皇后不能相互攻击到&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n&#xff0c;请你输出所有的满足条件的棋子摆法。 输入格式 共一行&#xff0c;包含整数 n。 输出…

回溯法求解n皇后问题

一、实验目的 1&#xff0e;掌握能用回溯法求解的问题应满足的条件&#xff1b; 2&#xff0e;加深对回溯法算法设计方法的理解与应用&#xff1b; 3&#xff0e;锻炼学生对程序跟踪调试能力&#xff1b; 4&#xff0e;通过本次实验的练习培养学生应用所学知识解决实际问题的能…

N皇后问题(java)

n皇后问题是一个以国际象棋为背景的问题&#xff1a;在nn的国际象棋棋盘上放置n个皇后&#xff0c;使得任何一个皇后都无法直接吃掉其他的皇后&#xff0c;即任意两个皇后都不能处于同一条横行、纵行或斜线上。 我们通过回溯的方法将所有可能的情况遍历一遍 假设现在有一个4*4…

N皇后问题(Python实现)

n 皇后问题研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 也就是说&#xff1a;存在一个N*N的棋盘&#xff0c;要放N个棋子&#xff0c;每个棋子不同行&#xff0c;不同列&#xff0c;不同&#xff08;正反&#xff09;对角线&…

数据结构之N皇后问题(C语言)

一、N皇后问题的概念 n 皇后问题&#xff0c;研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 一个皇后可以向水平、垂直以及向斜对角方向移动&#xff0c;如果一个皇后出现在另一个皇后的同一行&#xff0c;同一列或者斜对角&#x…

n皇后问题 C++

先上代码&#xff01; #include<iostream> using namespace std;const int N 20;int n; bool row[N],col[N], dg[N], udg[N]; char g[N][N];void dfs(int x, int y, int z) {if (y n) y 0, x; //判断y是否已经抵达边界&#xff0c;抵达后&#xff0c;x1进行下一行if …

回溯法-N皇后问题

一、N皇后问题 n皇后问题&#xff1a;要求在一个nn的棋盘上放置n个皇后&#xff0c;使得任意两个皇后不在同一行或同一列或同一斜线上。 二、回溯法 回溯法是一类非常重要的算法设计方法&#xff0c;有“通用解题法”之称。 回溯法&#xff08;探索与回溯法&#xff09;&am…

(新手向)N皇后问题详解(DFS算法)

非常经典的一道题&#xff1a; N皇后问题&#xff1a; 国际象棋中皇后的势力范围覆盖其所在的行、列以及两条对角线&#xff0c;现在考察如下问题&#xff1a;如何在n x n的棋盘上放置n个皇后&#xff0c;使得她们彼此互不攻击 。 免去麻烦我们这里假定n不是很大。。 &#…

n皇后问题-c语言实现

n皇后问题描述为:在一个nxn的棋盘上摆放n个皇后&#xff0c;要求任意两个皇后不能冲突&#xff0c;即任意两个皇后不在同一行、同一列或者同一斜线上。 1,1 1,2 1,3 1,4 2,1 2,2 2,3 2,4 3,1 3,2 3,3 3,4 4,1 4,2 4,3 4,4 上面是4皇后摆放方案&#xff0c;只有…

n皇后问题合集

八皇后问题是dfs的经典问题&#xff0c;目前遇到过的类型大致有这么几种&#xff1a; 1.经典n皇后问题 题目描述 n−皇后问题是指将 n 个皇后放在 nn 的国际象棋棋盘上&#xff0c;使得皇后不能相互攻击到&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。 …

N皇后问题(c语言实现)

问题描述&#xff1a; 有一个n*n的棋盘&#xff0c;在这个棋盘中放n个皇后&#xff0c;使得这n个皇后&#xff0c;任意两个皇后不在同一行&#xff0c;同一列&#xff0c;同一条对角线。例如&#xff0c;当n等于4时&#xff0c;有两种摆法。 输入只有一个整数n。 思路 如果…

N皇后问题

问题描述 n 皇后问题研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 上图为 8 皇后问题的一种解法。 给定一个整数 n&#xff0c;返回所有不同的 n 皇后问题的解决方案。 每一种解法包含一个明确的 n 皇后问题的棋子放置方案&#…

回溯算法之N皇后问题

问题描述 什么是皇后问题(有一定了解可以直接跳过这个部分看求解部分哦) 八皇后问题&#xff08;英文&#xff1a;Eight queens&#xff09;&#xff0c;是由国际西洋棋棋手马克斯贝瑟尔于1848年提出的问题&#xff0c;是回溯算法的典型案例。 问题表述为&#xff1a;在88格的…

N皇后问题(分支限界法)

问题描述&#xff1a; 在 n * n 格的棋盘上放置彼此不受攻击的 n 个皇后。按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题等价于在 n * n 的棋盘上放置 n 个皇后&#xff0c;任何 2个皇后不放在同一行或同一列或同一斜线上…

N皇后问题详解

文章目录 一、题目描述二、题目解析&#xff08;1&#xff09;思考一(集合回溯)&#xff08;2&#xff09;思考二(数组深度递归)&#xff08;3&#xff09;思考三(位运算) 一、题目描述 N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后&#xff0c; 要求&#xff1a;任何两个皇…

3.2 回溯法—N皇后问题

1. 问题描述 在 n n n\times n nn的棋盘上摆放 n n n个皇后&#xff0c;使任意两个皇后都不能处于同一行、同一列或同一斜线上 2. 问题分析 下以求解4皇后问题为例&#xff0c;分析4皇后问题的排列树以及回溯过程&#xff1a; 搜索及回溯过程&#xff1a; 解空间树&#…

【经典算法】N皇后问题

✨前言✨ N皇后问题经典的解决方案是暴力递归&#xff0c;其时间复杂度是O(2^n),因此常用来测试计算机的算力。今天我会给大家带来经典方法的详解&#xff0c;也会给大家展示N皇后优化后的大神解法。做一道经典题目&#xff0c;来一场思维旅行。 目录 ✨前言✨ &#x1f4a1;…