prometheus学习笔记之alertmanager告警配置

一、安装alertmanager

项目地址:https://github.com/prometheus/alertmanager

帮助文档:https://prometheus.io/docs/alerting/latest/alertmanager/

配置文档:https://prometheus.io/docs/alerting/latest/configuration/

wget https://github.com/prometheus/alertmanager/releases/download/v0.23.0/alertmanager-0.23.0.linux-amd64.tar.gz
tar xf alertmanager-0.23.0.linux-amd64.tar.gz -C /usr/local
cd  /usr/local
ln -sv alertmanager-0.24.0.linux-amd64 alertmanager

vim /etc/systemd/system/alertmanager.service
[Unit]
Description=Prometheus alertmanager
After=network.target

[Service]
ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml 
#建议指定--web.external-url参数,当alertmanager告警时会使用当前主机名称作为访问地址,当主机名称与实际地址不一致时,如使用代理的情况下,可以用该参数指定外部访问的地址,在告警模板中使用.ExternalURL 变量引用 [Install] WantedBy
=multi-user.target systemctl daemon-reload && systemctl restart alertmanager && systemctl enable alertmanager netstat -tnlp|grep alert

访问web页面 服务器地址:9093端口

二、配置alertmanager邮件告警配置

promnetheus告警流程

prometheus--->触发阈值--->超出持续时间--->alertmanager--->分组|抑制|静默--->媒体类型--->邮件|钉钉|微信等

分组(group): 将类似性质的警报合并为单个通知, 比如网络通知、 主机通知、 服务通知。
静默(silences): 是一种简单的特定时间静音的机制, 例如: 服务器要升级维护可以先设置这个时间段告警静默。
抑制(inhibition): 当警报发出后, 停止重复发送由此警报引发的其他警报即合并一个故障引起的多个报警事件, 可以消除冗余告警

1.配置alertmanager

vim alertmanager.yml #将文件修改如下
global:
  resolve_timeout: 1m  #在未收到新告警之前,告警状态的保持时间
  smtp_smarthost: 'smtp.qq.com:465' #邮箱服务商 SMTP地址
  smtp_from: '96xxxxx82@qq.com'    #发件人邮箱
  smtp_auth_username: '96xxxxx82@qq.com' #同smtp_from
  smtp_auth_password: 'gqlxxxioobylbdda'  #通常为邮箱的三方授权码
  smtp_hello: '@qq.com' # 给SMTP服务器自定义的的主机名
  smtp_require_tls: false  #是否使用TLS协议
route:
  group_by: ['alertname'] #通过alertname(告警名称)的值对告警进行分类 
  group_wait: 10s         #监控项第一次告警时的等待时间
  group_interval: 10s     #监控项恢复复第二次告警,那么告警间隔5分钟再发
  repeat_interval: 1m     #在最终发送消息前再等待5分钟, 5分钟后还没有恢复就发送第二次告警 实际每次告警间隔时间为 group_interval + repeat_interval
  receiver: 'email.hook'  #引用下面receivers中的某一个
receivers:
  - name: 'email.hook'
    email_configs:
      - to: 'panwenbin@cheryholding.com' #值为列表,可以写多个,建议设置邮件组,方便后续维护
send_resolved: true  #是否发送恢复告警,默认false inhibit_rules: #抑制告警的配置,通常默认即可,按级别抑制 如:critical级别的告警可以抑制warning级别的告警
- source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'dev', 'instance'] #对具有列表中相同标签的源告警才会做抑制 systemctl restart alertmanager

查看配置是否生效

2.配置prometheus

添加告警规则

cd /usr/local/prometheus
mkdir rules
vim rules/test1.yaml
groups:
  - name: alertmanager_pod.rules
    rules:
    - alert: Pod_all_cpu_usage
      expr: (sum by(name)(rate(container_cpu_usage_seconds_total{image!=""}[5m]))*100) > 1
      for: 2m
      labels:
        severity: critical
        service: pods
      annotations:
        description: 容器 {{ $labels.name }} CPU 资源利用率大于 10% , (current value is {{ $value }})
        summary: Dev CPU 负载告警
    - alert: Pod_all_memory_usage
      #expr: sort_desc(avg by(name)(irate(container_memory_usage_bytes{name!=""}[5m]))*100) > 10 #内存大于 10%
      expr: sort_desc(avg by(name)(irate(node_memory_MemFree_bytes {name!=""}[5m]))) > 2*1024*1024*1024 #内存大于 2G
      for: 2m
      labels:
        severity: critical
      annotations:
        description: 容 器 {{ $labels.name }} Memory 资 源 利 用 率 大 于 2G , (current value is {{ $value }})
        summary: Dev Memory 负载告警
    - alert: Pod_all_network_receive_usage
      expr: sum by (name)(irate(container_network_receive_bytes_total{container_name="POD"}[1m])) > 1
      for: 2m
      labels:
        severity: critical
      annotations:
        description: 容器 {{ $labels.name }} network_receive 资源利用率大于 50M , (current value is {{ $value }})
    - alert: Node 内存可用大小
      expr: node_memory_MemFree_bytes < 4*1024*1024*1024 #故意写错,已用于触发告警
      for: 2m
      labels:
        severity: critical
      annotations:
        description: Node节点可用内存小于 4GB

添加alertmanager配置及规则

vim prometheus.yml #新增或修改以下内容
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - 192.168.100.134:9093

rule_files:
  - "/usr/local/prometheus/rules/test1.yaml" #可以有多个

curl -X POST http://127.0.0.1:9090/-/reload

查看规则配置

3.查看告警

prometheus

alertmanager

查看告警邮件

告警恢复邮件

三、配置alertmanager钉钉告警配置 

1.创建钉钉群及群机器人

创建群后,点击群设置,点击机器人

添加机器人

添加自定义机器人

安全设置

 完成添加,复制token

配置参考:https://open.dingtalk.com/document/robots/custom-robot-access

SDK下载链接:https://open.dingtalk.com/document/resourcedownload/download-server-sdk

测试

msg='{"text":{"content":"alertname 123"},"msgtype":"text"}' #alertname为安全设置里面的关键字
curl -X POST -H "Content-Type: application/json"  -d "$(echo "$msg")"  https://oapi.dingtalk.com/robot/send?access_token=8b7eaxxx1e94ad6fd04d668b23f3e38xxxxxxxxxx #URL为创建机器人是生成的token地址

2.下载并启动prometheus-webhook-dingtalk

项目地址:https://github.com/timonwong/prometheus-webhook-dingtalk

wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v1.4.0/prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
tar xf prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz -C /usr/local/
cd /usr/local/
ln -sv prometheus-webhook-dingtalk-1.4.0.linux-amd64/ prometheus-webhook-dingtalk
cd prometheus-webhook-dingtalk
#测试,临时运行一下 .
/prometheus-webhook-dingtalk --web.listen-address="0.0.0.0:8060" --ding.profile="alertname=https://oapi.dingtalk.com/cess_token=8b7ea9726a1e94ad6fd04d668b23f3e38a0d6eed1daxxxxxxxxxa062" # profile名称与钉钉机器人关键字保持一致

3.配置alertmanager

新增钉钉接受配置并将路由指向钉钉

route:
  group_by: ['alertname'] #通过alertname(告警名称)的值对告警进行分类 
  group_wait: 10s         #监控项第一次告警时的等待时间
  group_interval: 10s     #监控项恢复复第二次告警,那么告警间隔5分钟再发
  repeat_interval: 5m     #在最终发送消息前再等待5分钟, 5分钟后还没有恢复就发送第二次告警 实际每次告警间隔时间为 group_interval + repeat_interval
  receiver: 'dingding'  #引用下面receivers中的某一个
receivers:
  - name: 'email.hook'
    email_configs:
      - to: 'panwenbin@cheryholding.com' #值为列表,可以写多个,建议设置邮件组,方便后续维护
        send_resolved: true  #是否发送恢复告警,默认false
  - name: 'dingding'
    webhook_configs:
      - url: 'http://192.168.100.134:8060/dingtalk/alertname/send' #值为列表,可以写多个,建议设置邮件组,方便后续维>护
        send_resolved: true  #是否发送恢复告警,默认false

systemctl restart alertmanager

4.修改prometheus指标产生或恢复告警

告警

恢复告警

四、微信告警 

1.企业微信机器人和应用

企业微信机器人和企业微信应用是两种不同的工具,它们各自具有独特的功能和用途。‌

企业微信机器人主要是一种自动化工具,旨在提高工作效率和沟通效率。它们能够通过接口实现在群里发送告警、提醒类的消息通知,通过配置可在工作群中自动推送信息,支持@提醒群聊中的所有人或特定同事, 例如发送定时消息或提醒,如工作提醒、总结汇报、企业数据实时监控等。这些功能通过企业微信提供的Webhook地址实现,需要自行开发或使用第三方服务来实现自动化推送功能‌
1企业微信修2022年之后修改了规则,需要在应用中添加可信的IP才能发消息,但是可信的IP需要企业微信进行备案后的域名

相比之下,企业微信应用则是一种更广泛的概念,它包括了企业微信中所有可以安装和使用的应用程序。这些应用可以是企业内部开发的,也可以是第三方开发的,用于满足各种业务需求。企业微信应用的功能范围非常广泛, 包括但不限于客户关系管理、任务管理、数据分析、员工沟通等。它们通常需要通过企业微信的管理后台进行配置和安装,可以集成到企业微信的各个部分,如聊天窗口、工作台等,以提供更丰富的功能和用户体验‌
2。 简单来说,企业微信机器人更侧重于自动化消息推送和提醒,而企业微信应用则提供了更广泛的功能和服务,旨在通过集成各种应用来提升企业内部的工作效率和团队协作能力。两者各有侧重,但都是为了提高企业的工作效率和团队协作效率而设计的工具‌

参考文档:https://work.weixin.qq.com/

2.创建企业微信

3.创建并配置企业应用告警

3.1点击应用管理,创建应用

可以创建接受告警的部门,如运维部,邀请自己加入,使得更符合实际环境

发送测试消息

下载并登录企业微信查看消息

3.2获取prometheus发送企业微信告警信息相关信息

企业ID:点击我的企业 最下方、

应用ID

应用secret

登录企业微信查看 

3.3添加可信IP

企业微信修2022年之后修改了规则,需要在应用中添加可信的IP,但是可信的IP需要填写备案后域名,否则会报 'not allow to access from your ip' 错误

https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwa5f876b936bd54bd&corpsecret=N2WppnFfQln4Fs22Kpvu6shFoHpYg-674VF8-xxx
{u'errcode': 60020, u'errmsg': u'not allow to access from your ip, hint: [1726216342464082740782233], from ip: 60.169.9.48, more info at https://open.work.weixin.qq.com/devtool/query?e=60020'}

3.4配置alertmanager

官方文档:https://prometheus.io/docs/alerting/latest/configuration/#wechat_config

vim alertmanager.yml
route:
  group_by: ['alertname'] #通过alertname(告警名称)的值对告警进行分类 
  receiver: 'wechat'  #引用下面receivers中的某一个
receivers:
  - name: 'wechat'
    wechat_configs:
      - corp_id: 'wwa5f876b9xxxd54bd'
        # to_party: 2 如果应用发送范围是全公司,想发送到指定部门使用to_party,填写部门ID,部门ID可以点击部门最右边三点,最下方有部门ID
        # to_user: '@all' all表示发送共所有人 因为可见范围为运维部,所以实际效果为发送共运维部所有人
        to_party: '2'
        agent_id: '1000002'
        api_secret: 'N2WppnFfQln4Fs22xxxxxoHpYg-674VF8-lEaNqM'
        send_resolved: true

systemctl restart alertmanager

部门ID查看

3.5修改prometheus告警规则并查看报警

3.6企业微信无法接受告警调试

由于alertmanager不告警也没有日志,所以需要使用其他工具进行调试,这样使用一个python脚本

yum install python-simplejson -y
vim wechat.py
#!/bin/python
#coding:utf-8
# 博客地址: https://knight.blog.csdn.net/article/details/106937276
# https://work.weixin.qq.com/?from=qyh_redirect
# 
 
import urllib,urllib2
import json
import sys
import simplejson
 
reload(sys)
sys.setdefaultencoding('utf-8')
 
def gettoken(corpid,corpsecret):
    gettoken_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' + corpid + '&corpsecret=' + corpsecret
    print  gettoken_url
    try:
        token_file = urllib2.urlopen(gettoken_url)
    except urllib2.HTTPError as e:
        print e.code
        print e.read().decode("utf8")
        sys.exit()
    token_data = token_file.read().decode('utf-8')
    token_json = json.loads(token_data)
    token_json.keys()
    token = token_json['access_token']
    return token
 
 
 
def senddata(access_token,user,subject,content):
 
    send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + access_token
    send_values = {
        "touser":"zhoulong",    #企业号中的用户帐号,在zabbix用户Media中配置,如果配置不正常,将按部门发送。
        "toparty":"2",    #部门ID
        "msgtype":"text", #消息类型。
        "agentid":"1000002",    #企业号中的应用id。
        "text":{
            "content":subject + '\n' + content
           },
        "safe":"0"
        }
 
    send_data = simplejson.dumps(send_values, ensure_ascii=False).encode('utf-8')
    send_request = urllib2.Request(send_url, send_data)
    response = json.loads(urllib2.urlopen(send_request).read())
    print str(response)
 
 
if __name__ == '__main__':
    user = str(sys.argv[1])     #zabbix传过来的第一个参数
    subject = str(sys.argv[2])  #zabbix传过来的第二个参数
    content = str(sys.argv[3])  #zabbix传过来的第三个参数
 
    corpid =  'ww2c68f6f17cafd1a1'   #CorpID是企业号的标识
    corpsecret = 'xxoo'  #corpsecretSecret是管理组凭证密钥
    accesstoken = gettoken(corpid,corpsecret)
    senddata(accesstoken,user,subject,content)

python wechat.py xx oo bb #测试是否能正常接受信息

4.企业微信机器人告警

4.1创建企业微信机器人

由于篇幅有限,请参考官方文档:https://hiflow.tencent.com/docs/applications/wwx-robot/

4.2手动验证告警

参考文档:https://developer.work.weixin.qq.com/document/path/91770

curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=979321ca-fc53-49e5-b3c3-6e7fcxxx' \
>    -H 'Content-Type: application/json' \
>    -d '
>    {
>     "msgtype": "text",
>     "text": {
>         "content": "hello world"
>     }
>    }'

正常返回结果:
{"errcode":0,"errmsg":"ok"}

4.3安装 PrometheusAlert

由于alertmanager不能直接调研webhook发送消息,通钉钉一样需要额外的工具进行消息转换,而官方只提供了企业微信应用的插件,没有提交微信机器人的插件,所有需要自己写或者使用三方的攻击,这里我们使用 PrometheusAlert

#下载安装包
wget https://github.com/feiyu563/PrometheusAlert/releases/download/v4.9.1/linux.zip
#解压并移动到/usr/local/下
unzip linux.zip
mv linux /usr/local/prometheusAlert

#修改prometheusAlert的配置文件,配置里有很多默认选项,这里主要看需要改动的几项,其他的不使用可以删除
cd /usr/local/prometheusAlert
vim conf/app.conf
#---------------------↓全局配置-----------------------
appname = PrometheusAlert
#登录用户名
login_user=prometheusalert
#登录密码
login_password=prometheusalert
#监听地址
httpaddr = "0.0.0.0"
#监听端口
httpport = 8080



#---------------------↓webhook-----------------------
#企业微信机器人相关配置
#是否开启微信告警通道,可同时开始多个通道0为关闭,1为开启
open-weixin=1
#默认企业微信机器人地址
wxurl=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx



#配置systemd管理
cat << EOF > /usr/lib/systemd/system/prometheusalert.service 
[Service]
ExecStart=/usr/local/prometheusAlert/PrometheusAlert
WorkingDirectory=/usr/local/prometheusAlert
Restart=always
[Install]
WantedBy=multi-user.target
[Unit]
Description=Prometheus Alerting Service
After=network.target
EOF

chmod +x /usr/local/prometheusAlert/PrometheusAlert
systemctl start prometheusalert
systemctl enable prometheusalert
netstat -tnlp|grep 8080

登录并进行告警测试

注:企业微信机器人目前已经支持 @某人 ,使用该功能需要通过企业微信管理后台取得对应用户的帐号,如下图 

4.4配置alertmanager告警
vim alertmanager.yml
route:
  receiver: 'prometheusalert' 
receivers:
  - name: 'prometheusalert'
    webhook_configs:
      #配置参考 https://github.com/feiyu563/PrometheusAlert/blob/master/doc/readme/conf-wechat.md  微信机器人可以配置多个,不配置则表示用prometheusalert配置文件中默认的机器人发送消息
      - url: 'http://192.168.100.134:8080/prometheusalert?type=wx&tpl=prometheus-wx&at=PanWenBin'  
        send_resolved: true  #是否发送恢复告警,默认false

curl -XPOST http://localhost:9093/-/reload

修改prometheus告警规则并验证

4.5 自定义模板
prometheusAlert自带了几个微信的模板,在调用时tpl指定模板名称即可,自带模板可以在控制台-->模板管理-->自定义模版中查看,也可以自己编写模板,可以参考其他人写的:https://github.com/feiyu563/PrometheusAlert/issues/30

五、飞书告警

1.创建飞书机器人

参考文档:https://open.feishu.cn/document/client-docs/bot-v3/bot-overview

创建飞书群-->群设置-->群机器人-->添加机器人-->自定义机器人-->修改头像、名称、描述或使用默认-->复制webhook地址

2.prometheusAlert添加飞书机器人配置

#是否开启飞书告警通道,可同时开始多个通道0为关闭,1为开启
open-feishu=1
#默认飞书机器人地址
fsurl=https://open.feishu.cn/open-apis/bot/v2/hook/7f3cd501-9a20-4578-add5-xxxxx

3.配置alertmanager告警

vim alertmanager.yml
route:
  receiver: 'feishu-bot' 
receivers:
  - name: 'feishu-bot'
    webhook_configs:
      - url: 'http://192.168.100.134:8080/prometheusalert?type=fs&tpl=prometheus-fs&at=all' #这里是at所有人 如果at单个人值为该用户的邮箱地址 参考文档:https://github.com/feiyu563/PrometheusAlert/blob/master/doc/readme/conf-feishu.md
        send_resolved: true  #是否发送恢复告警,默认false


curl -XPOST http://localhost:9093/-/reload

修改prometheus告警规则并验证

注:如果要修改告警标题可以在配置中修改title选项

配置文件参考: https://github.com/feiyu563/PrometheusAlert/blob/master/conf/app-example.conf

4.推荐模板

{{ $var := .externalURL}}{{ range $k,$v:=.alerts }}{{if eq $v.status "resolved"}}**[Prometheus恢复信息]({{$v.generatorURL}})**
*[{{$v.labels.alertname}}]({{$var}})*
告警级别:{{$v.labels.level}} #告警级别,注意lable取得是level
告警状态:{{$v.status}}  #增加了告警状态,源码总通过告警状态的不同而使用不同的颜色
开始时间:{{GetCSTtime  $v.startsAt}} #修改了时间显示。使用本地时间
结束时间:{{GetCSTtime $v.endsAt }} 
故障持续时间:{{GetTimeDuration $v.startsAt}} #增加故障持续时间,不太准
故障主机IP:{{$v.labels.instance}}
**{{$v.annotations.description}}**{{else}}**[Prometheus告警信息]({{$v.generatorURL}})**
*[{{$v.labels.alertname}}]({{$var}})*
告警级别:{{$v.labels.level}}
告警状态:{{$v.status}}
开始时间:{{GetCSTtime  $v.startsAt}}
故障持续时间:{{GetTimeDuration $v.startsAt}}
故障主机IP:{{$v.labels.instance}}
**{{$v.annotations.description}}**{{end}}{{ end }}
{{ $urimsg:=""}}{{ range $key,$value:=.commonLabels }}{{$urimsg =  print $urimsg $key "%3D%22" $value "%22%2C" }}{{end}}[*** 点我屏蔽该告警](http://192.168.100.134:9093/#/silences/new?filter=%7B{{SplitString $urimsg 0 -3}}%7D) #修改了alertmanager链接,默认localhost

效果如下

六、告警分类

使用场景:对不同级别的告警这种不同的告警媒介 

alertmanager配置

#主要通过告警规则中的标签进行分类,以下配置表示severity等于critical发送钉钉 serverity等于warning发送微信 其他发送走默认即邮件
route:
  group_by: ['alertname'] #通过alertname(告警名称)的值对告警进行分类 
  group_wait: 10s         #监控项第一次告警时的等待时间
  group_interval: 10s     #监控项恢复复第二次告警,那么告警间隔5分钟再发
  repeat_interval: 5m     #在最终发送消息前再等待5分钟, 5分钟后还没有恢复就发送第二次告警 实际每次告警间隔时间为 group_interval + repeat_interval
  receiver: 'email'  #引用下面receivers中的某一个
  routes:
  - receiver: dingding #critical 级别的消息发给钉钉
    group_wait: 10s
    match_re:
      severity: critical #在告警项中label定义的
continue: true #默认false 如果值为true,则不仅会发送到当前的receiver,同时还会发送到默认的receiver
- receiver: wechat #可以定义多个 group_wait: 10s match_re: severity: warning #在告警项中label定义的

自行修改prometheus告警配置,触发对应的告警查看是否收到告警

七、自定义消息模板并使用

默认的消息内容需要调整、 而且消息是连接在一起的

创建模板并引用

#alertmanager 中配置
mkdir template
vim template/message.tmpl
{{ define "wechat.default.message" }} #覆盖默认的wechat.default.message 其他看相应的文档
{{ range $i, $alert :=.Alerts }}
===alertmanager 监控报警===
告警状态: {{ .Status }}
告警级别: {{ $alert.Labels.severity }}
告警类型: {{ $alert.Labels.alertname }}
告警应用: {{ $alert.Annotations.summary }}
故障主机: {{ $alert.Labels.instance }}
告警主题: {{ $alert.Annotations.summary }}
触发阀值: {{ $alert.Annotations.value }}
告警详情: {{ $alert.Annotations.description }}
触发时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
===========end============
{{ end }}
{{ end }}

#引用模板
vim alertmanager.yml  #文件最后添加
templates:
  - '/usr/local/alertmanager/template/message.tmpl'

systemctl restart alertmanager

仅为微信告警,其他看官方文档或插件文档

 

posted @ 2024-09-20 15:45  百衲本  阅读(599)  评论(0编辑  收藏  举报
cnblogs_post_body { color: black; font: 0.875em/1.5em "微软雅黑" , "PTSans" , "Arial" ,sans-serif; font-size: 15px; } cnblogs_post_body h1 { text-align:center; background: #333366; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 23px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } cnblogs_post_body h2 { text-align:center; background: #006699; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 20px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } cnblogs_post_body h3 { background: #2B6695; border-radius: 6px 6px 6px 6px; box-shadow: 0 0 0 1px #5F5A4B, 1px 1px 6px 1px rgba(10, 10, 0, 0.5); color: #FFFFFF; font-family: "微软雅黑" , "宋体" , "黑体" ,Arial; font-size: 18px; font-weight: bold; height: 25px; line-height: 25px; margin: 18px 0 !important; padding: 8px 0 5px 5px; text-shadow: 2px 2px 3px #222222; } 回到顶部 博客侧边栏 回到顶部 页首代码 回到顶部 页脚代码