JAVA代码接入Aliyun日志服务SLS
最近有业务需求,需要看到接口调用次数、用户ip、平均响应时间、状态码等参数,这里使用日志服务SLS实现,在代码中接入Aliyun的日志服务,将日志信息上传到aliyun存储,采用Java代码作为例子,最后通过SQL查出相应的数据生成图表,最终效果如下:
创建日志存储
进入到阿里云的控制台,搜索日志服务SLS,创建日志过程点几下就行,这里留意三个参数Logstore名称和项目名称、访问端点,后面编程会用到
- Logstore名称

-
项目名称
-
访问端点
endpoint
发送日志
代码编写
-
将下列依赖加入到您项目的 pom.xml 中。
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>aliyun-log-producer</artifactId> <version>0.3.10</version> </dependency> <dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>aliyun-log</artifactId> <version>0.6.33</version> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>2.5.0</version> </dependency>
jar-with-dependency 版本,可以解决producer依赖的版本冲突
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>aliyun-log</artifactId> <version>0.6.35</version> <classifier>jar-with-dependencies</classifier> </dependency>
-
测试代码如下,填好参数后直接运行即可发送
public static void main(String[] args) throws InterruptedException, ProducerException { //基本参数 final String project = "xxxx-cn-shanghai-logproject"; final String logStore = "xxxx-app-api"; final String endpoint = "cn-shanghai.log.aliyuncs.com"; final String accessKeyId = "xxxxx"; final String accessKeySecret = "xxxxx"; //设置producer参数,后面有参数详细解析 ProducerConfig producerConfig = new ProducerConfig(); producerConfig.setBatchSizeThresholdInBytes(3 * 1024 * 1024); producerConfig.setBatchCountThreshold(10000); producerConfig.setIoThreadCount(10); final Producer producer = new LogProducer(producerConfig); producer.putProjectConfig(new ProjectConfig(project, endpoint, accessKeyId, accessKeySecret)); LOGGER.info("Test started."); //构建日志 LogItem logItem = new LogItem(); logItem.PushBack("request_method", "post"); logItem.PushBack("path", "/user/login"); //发送日志 producer.send( project, logStore, logItem); try { producer.close(); } catch (ProducerException e) { LOGGER.error("Failed to close producer, e=", e); } }
查看发送结果
在Logstore可以查看到新加的日志
ProducerConfig
ProducerConfig 用于配置发送策略,您可以根据不同的业务场景为参数指定不同的值,各参数含义如下表所示。
参数 | 类型 | 描述 |
---|---|---|
totalSizeInBytes | 整型 | 单个 producer 实例能缓存的日志大小上限,默认为 100MB。 |
maxBlockMs | 整型 | 如果 producer 可用空间不足,调用者在 send 方法上的最大阻塞时间,默认为 60 秒。 如果超过这个时间后所需空间仍无法得到满足,send 方法会抛出 TimeoutException。 如果将该值设为0,当所需空间无法得到满足时,send 方法会立即抛出 TimeoutException。 如果您希望 send 方法一直阻塞直到所需空间得到满足,可将该值设为负数。 |
ioThreadCount | 整型 | 执行日志发送任务的线程池大小,默认为可用处理器个数。 |
batchSizeThresholdInBytes | 整型 | 当一个 ProducerBatch 中缓存的日志大小大于等于 batchSizeThresholdInBytes 时,该 batch 将被发送,默认为 512 KB,最大可设置成 5MB。 |
batchCountThreshold | 整型 | 当一个 ProducerBatch 中缓存的日志条数大于等于 batchCountThreshold 时,该 batch 将被发送,默认为 4096,最大可设置成 40960。 |
lingerMs | 整型 | 一个 ProducerBatch 从创建到可发送的逗留时间,默认为 2 秒,最小可设置成 100 毫秒。 |
retries | 整型 | 如果某个 ProducerBatch 首次发送失败,能够对其重试的次数,默认为 10 次。 如果 retries 小于等于 0,该 ProducerBatch 首次发送失败后将直接进入失败队列。 |
maxReservedAttempts | 整型 | 每个 ProducerBatch 每次被尝试发送都对应着一个 Attempt,此参数用来控制返回给用户的 attempt 个数,默认只保留最近的 11 次 attempt 信息。 该参数越大能让您追溯更多的信息,但同时也会消耗更多的内存。 |
baseRetryBackoffMs | 整型 | 首次重试的退避时间,默认为 100 毫秒。 Producer 采样指数退避算法,第 N 次重试的计划等待时间为 baseRetryBackoffMs * 2^(N-1)。 |
maxRetryBackoffMs | 整型 | 重试的最大退避时间,默认为 50 秒。 |
adjustShardHash | 布尔 | 如果调用 send 方法时指定了 shardHash,该参数用于控制是否需要对其进行调整,默认为 true。 |
buckets | 整型 | 当且仅当 adjustShardHash 为 true 时,该参数才生效。此时,producer 会自动将 shardHash 重新分组,分组数量为 buckets。 如果两条数据的 shardHash 不同,它们是无法合并到一起发送的,会降低 producer 吞吐量。将 shardHash 重新分组后,能让数据有更多地机会被批量发送。 该参数的取值范围是 [1, 256],且必须是 2 的整数次幂,默认为 64。 |
最佳实践
生成Producer
应该单例模式使用Producer ,使用@Bean注解,在启动时注入Producer,后面从容器中取用
关闭Producer
-
**服务器上的Spring应用:**在aop类中继承DisposableBean,实现destroy()方法,在该方法中执行 Producer 的close()方法
-
**ServerLess上的HTTP函数:**编写接口/pre-stop,在接口中执行Producer 的close()方法
图表生成
生成图表必须先开启索引,新加的索引,不会统计之前的数据,需要的话可以进行索引重建,点击属性进行设置索引页面
使用自动生成索引可以很方便的添加索引

SQL案例
- 统计ip地区,及通过ip_to_province函数得出ip对应的省地址,用group by对地址聚合,用count函数计算出每个地址出现的次数 通过地图进行展示,鼠标悬浮可以展示,对应省的次数,图表类型–地图
* |
select
count(1) as c,
ip_to_province(client_ip) as address
group by
address
limit
100
-
访问前十的地址,通过split_part函数将request_uri按?分割成array,取分割后的第一个字符串,得出请求的路径,按这个路径group by进行聚合,用count函数计算每个路径访问的次数,用order by对次数进行排序,desc表示顺序是从大到小 通过表格进行展示,
图表类型–表格
* |
select
count(1) as pv,
split_part(uri, '?', 1) as path
group by
path
order by
pv desc
limit
10
- 请求状态及数量跟随时间顺序展示,通过 date_trunc 函数对日志时间按照分钟对齐,使用 date_format 函数提取出小时、分钟,将提取后的时间与访问状态码status通过group by聚合,获取每分钟每个状态码的count值, 最后使用流图展示数据,x轴为time,y轴count,聚合列是status,图表类型–流图pro
* |
select
date_format(date_trunc('minute', __time__), '%H:%i') as time,
COUNT(1) as c,
status
GROUP by
time,
status
ORDER by
time
LIMIT
1000
- 接口返回错误次数统计(前十),图表类型–表格
*|SELECT code,tip,COUNT(*) as num WHERE code != 0 GROUP by code,tip ORDER by num DESC LIMIT 10
- 统计用户代理访问次数,图表类型–表格
*|SELECT user_agent,COUNT(*) as num GROUP by user_agent ORDER by num DESC LIMIT 10
- 统计所有接口平均响应时间 ,图表类型–线图pro
* |
select
date_format(date_trunc('minute', __time__), '%H:%i') as time,
ceiling(avg(request_time)) as avg_request_time
WHERE status = 200
GROUP by
time
ORDER by
time
评论