4e0a1122554a0ccd2ff1ce164f49268e.png

(2021年倒计时33天)

书接上文,在上回书中,我们说到了《微服务组件记事本:Skywalking执行效果 · 多图篇》,文章比较详细的展示了Skywalking中的各种数据和图表展示,有些小伙伴群里问我,这些图表能不能控制展示或隐藏?这些图表又是对应的什么意思?能否查看具体的数据内容么?答案都是肯定的,如果你要是使用MySql作为持久化方案,可能看起来更直观些,毕竟我们使用数据库都好多年了。不过官方更建议的是使用ElasticSearch(下文统称ES)来做持久化方案,所以今天咱们就来看看ES来记录Skywalking数据,都有哪些索引。

本文建议收藏下,方便以后即时查询,必须在微服务中Skywalking这类的APM应用是刚需。

3f39ffaea1624072ed807e35e0ce559f.png

ES 索引概括和地址

用ES来存储Skywalking数据,每天会生成114个索引,这个不是动态的哟,而是官方定义好的,当然你也可以自己根据需要做其他兼容,这个另说了。114个索引中,分成五大模块,约十个小模块,今天咱们都具体说说每个模块都有哪些索引(注意:本文说到的是Skywalking-aop的8.3.0版本,其他版本可能有细微差别)。

那如何来寻找这些索引呢,很简单。

1、直接页面内查找,这种方式很简单,其实页面第一个banner仪表盘中的图表,每一个都会是一个或多个索引,注意不是一对一或者唯一的哟,因为一个索引可能存在与多个图表上,至于如何寻找,可以看左上角的那个小锁,点一下就有惊喜。

d0ec090a70ff84bd5d59724b4c923b6d.png

2、直接在页面上看,也只能看到索引名,那每个名字什么意思,或者如何计算呢,可以直接看官方配置文件。

启动OAP服务(本文统一都是用DOCKER来启动的,启动过程可以看我之前写的《微服务组件记事本:本地搭建Skywalking》文章),启动后,进入容器,然后在config文件夹下会看到一个oal的文件夹。

8ff73e6e5f76c653ade19440ed4915ec.png

进入oal文件夹,会看到有五个*.oal文件:

browser.oal       
core.oal            
dotnet-agent.oal  
envoy.oal         
java-agent.oal

OAL含义是观测分析语言(Observability Analysis Language),是Skywalking用来分析流入的数据。OAL专注于服务、服务实例以及端点的度量指标,因此OAL非常易于学习和使用,你也同时可以简单地改变和重新启动服务器,使其有效。OAL脚本本书是编译语言,通过OAL运行时动态生成Java代码。

你可以在环境变量中设置SW_OAL_ENGINE_DEBUG=Y,查看生成了哪些类。

上边七个文件从名字上,我们就能对其功能可见一斑,浏览器、核心(指服务)、两个探针(dotnet和java)和envoy相关。

c9504d525ba8ca206d3787d86b7250d3.png

浏览器模块:browser.oal(33)

我们查看下browser.oal文件,可以看到很多的索引名称和计算方式,咱们分成2个子模块来说,打开Skywalking-ui看到仪表盘-WebBrowser栏目下,有两个子模块,分别是Web APP指标和Pages指标:

031e1ee71e47bc2bdb3ba38907ed6f85.png

Web App 子模块(6个索引)

// app的pv数
browser_app_pv = from(BrowserAppTraffic.count).filter(trafficCategory == BrowserAppTrafficCategory.NORMAL).sum();
// app的错误率
browser_app_error_rate = from(BrowserAppTraffic.*).rate(trafficCategory == BrowserAppTrafficCategory.FIRST_ERROR,trafficCategory == BrowserAppTrafficCategory.NORMAL);
// app的错误数
browser_app_error_sum = from(BrowserAppTraffic.count).filter(trafficCategory != BrowserAppTrafficCategory.NORMAL).sum();


// app单一版本的pv数
browser_app_single_version_pv = from(BrowserAppSingleVersionTraffic.count).filter(trafficCategory == BrowserAppTrafficCategory.NORMAL).sum();
// app单一版本的错误率
browser_app_single_version_error_rate = from(BrowserAppSingleVersionTraffic.trafficCategory).rate(trafficCategory == BrowserAppTrafficCategory.FIRST_ERROR,trafficCategory == BrowserAppTrafficCategory.NORMAL);
// app单一版本的错误总数
browser_app_single_version_error_sum = from(BrowserAppSingleVersionTraffic.count).filter(trafficCategory != BrowserAppTrafficCategory.NORMAL).sum();

Pages 页面子模块(27个索引)

// 页面的pv数
browser_app_page_pv = from(BrowserAppPageTraffic.count).filter(trafficCategory == BrowserAppTrafficCategory.NORMAL).sum();
// 页面错误率
browser_app_page_error_rate = from(BrowserAppPageTraffic.*).rate(trafficCategory == BrowserAppTrafficCategory.FIRST_ERROR,trafficCategory == BrowserAppTrafficCategory.NORMAL);
// 页面错误总数
browser_app_page_error_sum = from(BrowserAppPageTraffic.count).filter(trafficCategory != BrowserAppTrafficCategory.NORMAL).sum();


// 页面ajax请求错误数
browser_app_page_ajax_error_sum = from(BrowserAppPageTraffic.count).filter(trafficCategory != BrowserAppTrafficCategory.NORMAL).filter(errorCategory == BrowserErrorCategory.AJAX).sum();
// 页面资源请求错误数
browser_app_page_resource_error_sum = from(BrowserAppPageTraffic.count).filter(trafficCategory != BrowserAppTrafficCategory.NORMAL).filter(errorCategory == BrowserErrorCategory.RESOURCE).sum();
// 页面js执行错误数
browser_app_page_js_error_sum = from(BrowserAppPageTraffic.count).filter(trafficCategory != BrowserAppTrafficCategory.NORMAL).filter(errorCategory in [BrowserErrorCategory.JS,BrowserErrorCategory.VUE,BrowserErrorCategory.PROMISE]).sum();
// 页面未知异常错误数
browser_app_page_unknown_error_sum = from(BrowserAppPageTraffic.count).filter(trafficCategory != BrowserAppTrafficCategory.NORMAL).filter(errorCategory == BrowserErrorCategory.UNKNOWN).sum();


// 页面平均跳转时间
browser_app_page_redirect_avg = from(BrowserAppPagePerf.redirectTime).longAvg();
// 页面平均dns时间
browser_app_page_dns_avg = from(BrowserAppPagePerf.dnsTime).longAvg();
// 页面平均响应时间
browser_app_page_ttfb_avg = from(BrowserAppPagePerf.ttfbTime).longAvg();
// 页面平均tcp连接时间
browser_app_page_tcp_avg = from(BrowserAppPagePerf.tcpTime).longAvg();
// 页面平均trans时间
browser_app_page_trans_avg = from(BrowserAppPagePerf.transTime).longAvg();
// 页面平均dom分析时间
browser_app_page_dom_analysis_avg = from(BrowserAppPagePerf.domAnalysisTime).longAvg();
// 页面平均fpt时间
browser_app_page_fpt_avg = from(BrowserAppPagePerf.fptTime).longAvg();
// 页面平均dom准备时间
browser_app_page_dom_ready_avg = from(BrowserAppPagePerf.domReadyTime).longAvg();
// 页面平均加载完成时间
browser_app_page_load_page_avg = from(BrowserAppPagePerf.loadPageTime).longAvg();
// 页面平均响应时间
browser_app_page_res_avg = from(BrowserAppPagePerf.resTime).longAvg();
// 页面平均ssl时间
browser_app_page_ssl_avg = from(BrowserAppPagePerf.sslTime).longAvg();
// 页面平均生存时间
browser_app_page_ttl_avg = from(BrowserAppPagePerf.ttlTime).longAvg();
// 页面平均首包时间
browser_app_page_first_pack_avg = from(BrowserAppPagePerf.firstPackTime).longAvg();
// 页面平均首次绘画完成时间
browser_app_page_fmp_avg = from(BrowserAppPagePerf.fmpTime).longAvg();


// 以下均是功能指标:包括 p50, p75, p90, p95, p99
browser_app_page_fpt_percentile = from(BrowserAppPagePerf.fptTime).percentile(10);
browser_app_page_ttl_percentile = from(BrowserAppPagePerf.ttlTime).percentile(10);
browser_app_page_dom_ready_percentile = from(BrowserAppPagePerf.domReadyTime).percentile(10);
browser_app_page_load_page_percentile = from(BrowserAppPagePerf.loadPageTime).percentile(10);
browser_app_page_first_pack_percentile = from(BrowserAppPagePerf.firstPackTime).percentile(10);
browser_app_page_fmp_percentile = from(BrowserAppPagePerf.fmpTime).percentile(10);

7724799623224a206c8fb0118453ce7d.png

核心服务模块:core.oal(38)

服务相关的索引,基本都是在仪表盘-APM和Database菜单里,而在APM栏目里又有四个子栏目,因此分成五个部分。分别是全局指标、服务间指标、服务实例指标、终端指标、数据库指标。

706f27e2323e2a8425f1dbc8109d60f1.png

APM全局指标(7个索引)

// Multiple values including p50, p75, p90, p95, p99
all_percentile = from(All.latency).percentile(10);   
all_heatmap = from(All.latency).histogram(100, 20);


// 服务的平均响应时间
service_resp_time = from(Service.latency).longAvg();
// 服务的请求成功率
service_sla = from(Service.*).percent(status == true);
// 服务的每分钟调用次数
service_cpm = from(Service.*).cpm();
// Multiple values including p50, p75, p90, p95, p99
service_percentile = from(Service.latency).percentile(10); 
// 服务的apdex应用性能指标
service_apdex = from(Service.latency).apdex(name, status);

服务之间调用指标(8个索引)

// 在客户端检测每分钟调用次数
service_relation_client_cpm = from(ServiceRelation.*).filter(detectPoint == DetectPoint.CLIENT).cpm();
// 在服务端检测每分钟调用次数
service_relation_server_cpm = from(ServiceRelation.*).filter(detectPoint == DetectPoint.SERVER).cpm();
// 在客户端检测到的成功率
service_relation_client_call_sla = from(ServiceRelation.*).filter(detectPoint == DetectPoint.CLIENT).percent(status == true);
// 在服务端检测到的成功率
service_relation_server_call_sla = from(ServiceRelation.*).filter(detectPoint == DetectPoint.SERVER).percent(status == true);
// 在客户端检测到的平均响应时间
service_relation_client_resp_time = from(ServiceRelation.latency).filter(detectPoint == DetectPoint.CLIENT).longAvg();
// 在服务端检测到的平均响应时间
service_relation_server_resp_time = from(ServiceRelation.latency).filter(detectPoint == DetectPoint.SERVER).longAvg();
// Multiple values including p50, p75, p90, p95, p99
service_relation_client_percentile = from(ServiceRelation.latency).filter(detectPoint == DetectPoint.CLIENT).percentile(10); 
service_relation_server_percentile = from(ServiceRelation.latency).filter(detectPoint == DetectPoint.SERVER).percentile(10);

服务实例之间的调用指标(11个索引)

// 在客户端实例检测到的每分钟调用次数
service_instance_relation_client_cpm = from(ServiceInstanceRelation.*).filter(detectPoint == DetectPoint.CLIENT).cpm();
// 在服务端实例检测到的每分钟调用次数
service_instance_relation_server_cpm = from(ServiceInstanceRelation.*).filter(detectPoint == DetectPoint.SERVER).cpm();
// 在客户端实例检测到的成功率
service_instance_relation_client_call_sla = from(ServiceInstanceRelation.*).filter(detectPoint == DetectPoint.CLIENT).percent(status == true);
// 在服务端实例检测到的成功率
service_instance_relation_server_call_sla = from(ServiceInstanceRelation.*).filter(detectPoint == DetectPoint.SERVER).percent(status == true);
// 在客户端实例检测到的平均响应时间
service_instance_relation_client_resp_time = from(ServiceInstanceRelation.latency).filter(detectPoint == DetectPoint.CLIENT).longAvg();
// 在服务端实例检测到的平均响应时间
service_instance_relation_server_resp_time = from(ServiceInstanceRelation.latency).filter(detectPoint == DetectPoint.SERVER).longAvg();
// Multiple values including p50, p75, p90, p95, p99
service_instance_relation_client_percentile = from(ServiceInstanceRelation.latency).filter(detectPoint == DetectPoint.CLIENT).percentile(10); 
service_instance_relation_server_percentile = from(ServiceInstanceRelation.latency).filter(detectPoint == DetectPoint.SERVER).percentile(10); 


// 服务实例的成功率
service_instance_sla = from(ServiceInstance.*).percent(status == true);
// 服务实例的平均响应时间
service_instance_resp_time= from(ServiceInstance.latency).longAvg();
// 服务实例的每分钟调用次数
service_instance_cpm = from(ServiceInstance.*).cpm();

端点指标(8个索引)

// 端点的每分钟调用次数
endpoint_cpm = from(Endpoint.*).cpm();
// 端口平均响应时间
endpoint_avg = from(Endpoint.latency).longAvg();
// 端点的成功率
endpoint_sla = from(Endpoint.*).percent(status == true);
// Multiple values including p50, p75, p90, p95, p99
endpoint_percentile = from(Endpoint.latency).percentile(10); // Multiple values including p50, p75, p90, p95, p99


// 在服务端端点检测到的每分钟调用次数
endpoint_relation_cpm = from(EndpointRelation.*).filter(detectPoint == DetectPoint.SERVER).cpm();
// 在服务端检测到的rpc调用的平均耗时
endpoint_relation_resp_time = from(EndpointRelation.rpcLatency).filter(detectPoint == DetectPoint.SERVER).longAvg();
// 在服务端检测到的请求成功率
endpoint_relation_sla = from(EndpointRelation.*).filter(detectPoint == DetectPoint.SERVER).percent(status == true);
// Multiple values including p50, p75, p90, p95, p99
endpoint_relation_percentile = from(EndpointRelation.rpcLatency).filter(detectPoint == DetectPoint.SERVER).percentile(10);

数据库性能指标(4个索引)

// 数据库的处理平均响应时间
database_access_resp_time = from(DatabaseAccess.latency).longAvg();
// 数据库的请求成功率
database_access_sla = from(DatabaseAccess.*).percent(status == true);
// 数据库的每分钟调用次数
database_access_cpm = from(DatabaseAccess.*).cpm();
// Multiple values including p50, p75, p90, p95, p99
database_access_percentile = from(DatabaseAccess.latency).percentile(10);

f6e9c4a7e41100fb1a7902d9c1e3a3f6.png

agent模块1:java-agent.oal(12)

// jvm 平均cpu耗时百分比
instance_jvm_cpu = from(ServiceInstanceJVMCPU.usePercent).doubleAvg();
// jvm 堆空间的平均使用空间
instance_jvm_memory_heap = from(ServiceInstanceJVMMemory.used).filter(heapStatus == true).longAvg();
// jvm 非堆空间的平均使用空间
instance_jvm_memory_noheap = from(ServiceInstanceJVMMemory.used).filter(heapStatus == false).longAvg();
// jvm 最大堆内存的平均值
instance_jvm_memory_heap_max = from(ServiceInstanceJVMMemory.max).filter(heapStatus == true).longAvg();
// jvm 最大非堆内存的平均值
instance_jvm_memory_noheap_max = from(ServiceInstanceJVMMemory.max).filter(heapStatus == false).longAvg();
// 年轻代gc的耗时
instance_jvm_young_gc_time = from(ServiceInstanceJVMGC.time).filter(phrase == GCPhrase.NEW).sum();
// 老年代gc的耗时
instance_jvm_old_gc_time = from(ServiceInstanceJVMGC.time).filter(phrase == GCPhrase.OLD).sum();
// 年轻代gc的次数
instance_jvm_young_gc_count = from(ServiceInstanceJVMGC.count).filter(phrase == GCPhrase.NEW).sum();
// 老年代gc的次数
instance_jvm_old_gc_count = from(ServiceInstanceJVMGC.count).filter(phrase == GCPhrase.OLD).sum();
// 存活的线程数
instance_jvm_thread_live_count = from(ServiceInstanceJVMThread.liveCount).longAvg();
// 守护线程数
instance_jvm_thread_daemon_count = from(ServiceInstanceJVMThread.daemonCount).longAvg();
// 峰值线程数
instance_jvm_thread_peak_count = from(ServiceInstanceJVMThread.peakCount).longAvg();

c2e4e3f8ef8cb1fa15f02c4e92c30ae1.png

agent 模块2:dotnet-agent.oal(9)

相关的内容和java的很类似,这里就不描述了。

instance_clr_cpu = from(ServiceInstanceCLRCPU.usePercent).doubleAvg();
instance_clr_gen0_collect_count = from(ServiceInstanceCLRGC.gen0CollectCount).sum();
instance_clr_gen1_collect_count = from(ServiceInstanceCLRGC.gen1CollectCount).sum();
instance_clr_gen2_collect_count = from(ServiceInstanceCLRGC.gen2CollectCount).sum();
instance_clr_heap_memory = from(ServiceInstanceCLRGC.heapMemory).longAvg();
instance_clr_available_completion_port_threads = from(ServiceInstanceCLRThread.availableCompletionPortThreads).max();
instance_clr_available_worker_threads = from(ServiceInstanceCLRThread.availableWorkerThreads).max();
instance_clr_max_completion_port_threads = from(ServiceInstanceCLRThread.maxCompletionPortThreads).max();
instance_clr_max_worker_threads = from(ServiceInstanceCLRThread.maxWorkerThreads).max();

ca8538bb06a6552e5aeeb4e13b9960f4.png

envoy模块:envoy.oal(3)

envoy_heap_memory_max_used = from(EnvoyInstanceMetric.value).filter(metricName == "server.memory_heap_size").maxDouble();
envoy_total_connections_used = from(EnvoyInstanceMetric.value).filter(metricName == "server.total_connections").maxDouble();
envoy_parent_connections_used = from(EnvoyInstanceMetric.value).filter(metricName == "server.parent_connections").maxDouble();

到了这里,应说到了五个*.oal的95个索引,剩下的19个索引主要是这些。

8fd40840cd01a1b365182df2cc041075.png

其他索引(19)

这些索引并没有存在于上边的oal文件里,但是每天都会生成的,具体在哪里执行的,待我后续研究下吧。

alarm_record
browser_error_log
endpoint_relation_server_side
endpoint_traffic
http_access_log
instance_traffic
jaeger_span
network_address_alias
profile_task
profile_task_log
profile_task_segment_snapshot
segment
service_instance_relation_client_side
service_instance_relation_server_side
service_relation_client_side
service_relation_server_side
service_traffic
top_n_database_statement
zipkin_span

好啦,今天就暂时这样吧,记录了下使用ES存储Skywalking的数据索引,如果想对数据有进一步了解,可以配置下Mysql试试哟。

点击【阅读原文】,查看更多持久化方案👇

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐