Published on

Elastic APM 前端监控实践笔记

Authors
  • avatar
    Name
    Terry
    Twitter

在现代部署中,传统的手工安装流程基本可以省略。更推荐基于 Docker 进行部署,直接复用官方或社区提供的 Docker 镜像与 compose 文件,从而获得更一致、更可复现的环境。

介绍

Q: What is APM?

A: Free and open application performance monitoring

Elastic APM is an application performance monitoring system built on the Elastic Stack. It allows you to monitor software services and applications in real-time, by collecting detailed performance information on response time for incoming requests, database queries, calls to caches, external HTTP requests, and more. This makes it easy to pinpoint and fix performance problems quickly. Elastic APM also automatically collects unhandled errors and exceptions. Errors are grouped based primarily on the stack trace, so you can identify new errors as they appear and keep an eye on how many times specific errors happen. Metrics are another vital source of information when debugging production systems. Elastic APM agents automatically pick up basic host-level metrics and agent-specific metrics, like JVM metrics in the Java Agent, and Go runtime metrics in the Go Agent.

APM Server

APM Server 是 Elastic 家的前端性能监控方案的关键组件。它接收 Elastic APM agents 上报的数据,写入 Elasticsearch 进行存储,最终在 Kibana 中完成可视化与分析。

架构图

安装前提

apm-server 依赖 ELK,因此在安装 apm-server 之前至少需要启动 Elasticsearch 与 Kibana。Elastic 官方提供了 ELK 的镜像,我们可以通过 Docker 快速启动。docker-compose.yml 的主体结构示例:

version: "3"
services:
    elasticsearch:
      image: elasticsearch:${ELK_VERSION}
      ports:
        - "9200:9200"
        - "9300:9300"
      networks:
        - elk
    kibana:
      image: kibana:${ELK_VERSION}
      ports:
        - "5601:5601"
      depends_on:
        - elasticsearch
      networks:
        - elk
    apm-server:
      image: elastic/apm-server:${ELK_VERSION}
      ports:
        - "8200:8200"
      depends_on:
        - elasticsearch
      networks:
        - elk
networks:
  elk:
    driver: bridge

其中变量声明在 .env 文件中,版本可自定,但不建议使用 latest,应明确指定:

ELK_VERSION=8.11.0

除此之外,ELK 的初始化配置也很关键。 按上述最小配置启动后(docker-compose up),访问 localhost:5601 通常会看到如下界面: Alt text

点击Where do I find this?,可以看到:

The enrollment token is automatically generated when you start Elasticsearch for the first time. You might need to scroll back a bit in the terminal to view it.

To generate a new enrollment token, run the following command from the Elasticsearch installation directory:

bin/elasticsearch-create-enrollment-token --scope kibana

所以进入Elasticsearch容器的/usr/share/elasticsearch目录,执行上述命令即可。然后复制生成的token,输入后进入下一步,Verification required: Alt text

Copy the code from the Kibana server or run bin/kibana-verification-code to retrieve it.

所以按照指示,进入kibana容器的/usr/share/kibana目录,执行上述命令,填入生成的验证码即可。若上述步骤没有问题,接下来就会来到登录界面:

Alt text

内建用户(Built-in users)

官网有介绍内建用户的文章:Built-in users

  • elastic

    A built-in superuser.

  • kibana_system

    The user Kibana uses to connect and communicate with Elasticsearch.

  • logstash_system

    The user Logstash uses when storing monitoring information in Elasticsearch.

  • beats_system

    The user the Beats use when storing monitoring information in Elasticsearch.

  • apm_system

    The user the APM server uses when storing monitoring information in Elasticsearch.

  • remote_monitoring_user

鉴权注意事项

Starting with Elastic v8.0.0, it is no longer possible to run Kibana using the bootstraped privileged elastic user.

也就是说,自 v8 起,不能使用默认密码的超级用户 elastic 直接登录 Kibana。若需使用 elastic 登录,需要先重置或修改该用户密码。

Alt text

Elasticsearch 自 6.8 起向免费用户开放 X-Pack 的安全功能,并默认开启。若关闭,许多能力将不可用(例如 Kibana 无法连接 Elasticsearch)。请勿为图省事而将 xpack.security.enabled=false,生产环境务必开启安全特性。

WARN LOG

可能会遇到Elasticsearch showing received plaintext http traffic on an https channel in console问题。

修改密码

有三种修改密码的方式。

方法一、启动前修改配置文件

.env文件里添加变量:

ELASTIC_PASSWORD=your_password_here

随后在 docker-compose.yml 中将环境变量映射到 Elasticsearch 配置:

version: "3"
services:
    elasticsearch:
      image: elasticsearch:${ELK_VERSION}
      ports:
        - "9200:9200"
        - "9300:9300"
      environment:
      # ":-" 表示使用默认值。具体来说,这个语法表示如果ELASTIC_PASSWORD已经定义了,那么使用它的值;如果没有定义,那么就使用默认值,这里的默认值是空。
        ELASTIC_PASSWORD: ${ELASTIC_PASSWORD:-}
      networks:
        - elk

重启 docker-compose up 后,使用 elastic 与新密码登录即可。

方法二、命令行修改

Elasticsearch 安装目录的 /bin 文件夹里有很多工具,其中就包括设置以及修改密码的工具。

设置密码
sh-5.0$ bin/elasticsearch-setup-passwords interactive

******************************************************************************
Note: The 'elasticsearch-setup-passwords' tool has been deprecated. This       command will be removed in a future release.
******************************************************************************

Initiating the setup of passwords for reserved users elastic,apm_system,kibana,kibana_system,logstash_system,beats_system,remote_monitoring_user.
You will be prompted to enter passwords as the process progresses.
Please confirm that you would like to continue [y/N]
修改密码
sh-5.0$ bin/elasticsearch-reset-password --interactive -u elastic

This tool will reset the password of the [elastic] user.
You will be prompted to enter the password.
Please confirm that you would like to continue [y/N]y


Enter password for [elastic]: 
Re-enter password for [elastic]: 
Password for the [elastic] user successfully reset.
新增用户
sh-5.0$ elasticsearch-users -h
Manages elasticsearch file users

Commands
--------
useradd - Adds a file user
userdel - Deletes a file based user
passwd - Changes the password of an existing file based user
roles - Edit roles of an existing user
list - List existing file based users and their corresponding roles

Non-option arguments:
command              

Option             Description        
------             -----------        
-E <KeyValuePair>  Configure a setting
-h, --help         Show help          
-s, --silent       Show minimal output
-v, --verbose      Show verbose output


sh-5.0$ elasticsearch-users useradd esadmin
Enter new password: 
Retype new password:
权限控制

查看上面的输出,可以看到该命令还能删除用户,编辑权限等:

sh-5.0$ elasticsearch-users roles -h     
Edit roles of an existing user

The roles command allows editing roles for file based users.
You can also list a user's roles by omitting the -a and -r
parameters.

Non-option arguments:
username             

Option             Description                                              
------             -----------                                              
-E <KeyValuePair>  Configure a setting                                      
-a, --add          Adds supplied roles to the specified user (default: )    
-h, --help         Show help                                                
-r, --remove       Remove supplied roles from the specified user (default: )
-s, --silent       Show minimal output                                      
-v, --verbose      Show verbose output 

比如我刚创建的 esadmin 用户现在还不能登录 Kibana:![Alt text](/static/images/post/CleanShot 2023-11-11 at 15.18.46.png)

添加下列权限后就可以成功登录了。(具体权限查看Built-in roles

sh-5.0$ elasticsearch-users roles -a kibana_system esadmin
sh-5.0$ elasticsearch-users roles -a superuser esadmin

查看权限:

sh-5.0$ elasticsearch-users roles -v esadmin
esadmin        : kibana_system,superuser

这一部分非常感谢这篇博客ELK Kibana 8.3.2登录认证, 我是从这篇博客了解到该知识并顺藤摸瓜摸到官方文档的。

方法三、ES API 修改

这部分也是从docker中设置elasticsearch、kibana用户名密码、修改密码受到的启发。

在kibana的Dev Tools Console修改

要使用该方法,建议先了解 curl 的基础用法,可参考:阮一峰 · curl 快速参考

修改密码的API参考:Change passwords API

比如:

POST /_security/user/elastic/_password
{
  "password" : "helloworld"
}

或者还可以在终端通过curl直接修改。

终端curl修改
curl -XPOST -D- 'http://localhost:9200/_security/user/esadmin/_password' \
    -H 'Content-Type: application/json' \
    -u elastic:helloworld \
    -d '{"password" : "helloworldagain"}'

上述方式在某些环境下可能因安全配置导致失败,出现 curl: (52) Empty reply from server。可检查网络与证书配置,或改用控制台/Dev Tools 完成操作。

TL;DR;

最终的最简单的配置:

.env

ELK_VERSION=8.11.0
ELASTIC_PASSWORD='changeme'
KIBANA_SYSTEM_PASSWORD='changeme'
APM_SYSTEM_PASSWORD='changeme'

docker-compose.yml

version: "3"
services:
    elasticsearch:
      image: elasticsearch:${ELK_VERSION}
      ports:
        - "9200:9200"
        - "9300:9300"
      environment:
      # ":-" 表示默认值:若 ELASTIC_PASSWORD 已定义则使用其值,否则为空
        ELASTIC_PASSWORD: ${ELASTIC_PASSWORD:-}
      networks:
        - elk
    kibana:
      image: kibana:${ELK_VERSION}
      ports:
        - "5601:5601"
      environment:
        KIBANA_SYSTEM_PASSWORD: ${KIBANA_SYSTEM_PASSWORD:-}
        I18N_LOCALE: zh-CN
      depends_on:
        - elasticsearch
      networks:
        - elk
    apm-server:
      image: elastic/apm-server:${ELK_VERSION}
      ports:
        - "8200:8200"
      environment:
        APM_SYSTEM_PASSWORD: ${APM_SYSTEM_PASSWORD:-}
      depends_on:
        - elasticsearch
      networks:
        - elk
networks:
  elk:
    driver: bridge

安装APM插件

https://www.elastic.co/guide/en/apm/guide/current/configuration-rum.html

https://www.elastic.co/guide/en/apm/agent/rum-js/current/angular-integration.html

https://www.elastic.co/guide/en/elasticsearch/reference/8.1/service-accounts.html

Alt text

最后的apm-server.yml:

apm-server:
  host: apm-server:8200
  frontend.enabled: true
  frontend.allow_origins: "*"
  rum:
    enabled: true
    allow_origins: ['*']
    allow_headers: ["header1", "header2"]
    library_pattern: "node_modules|bower_components|~"
    exclude_from_grouping: "^/webpack"
  auth:
    anonymous:
        rate_limit.event_limit: 300
        rate_limit.ip_limit: 1000
        allow_service: ['my-service-name', 'hello-world']

output.elasticsearch:
  enabled: true
  hosts: ["elasticsearch:9200"]
  username: "logadmin" 
  password: "123456"

setup.kibana:
  host: "kibana"
  username: "logadmin" 
  password: "123456"

Source Map

https://www.elastic.co/guide/en/apm/guide/current/source-map-how-to.html

https://angular.cn/guide/workspace-config#complex-configuration-values

官方文档