(2021年倒计时33天)
书接上文,在上回书中,我们说到了《微服务组件记事本:Skywalking执行效果 · 多图篇》,文章比较详细的展示了Skywalking中的各种数据和图表展示,有些小伙伴群里问我,这些图表能不能控制展示或隐藏?这些图表又是对应的什么意思?能否查看具体的数据内容么?答案都是肯定的,如果你要是使用MySql作为持久化方案,可能看起来更直观些,毕竟我们使用数据库都好多年了。不过官方更建议的是使用ElasticSearch(下文统称ES)来做持久化方案,所以今天咱们就来看看ES来记录Skywalking数据,都有哪些索引。
本文建议收藏下,方便以后即时查询,必须在微服务中Skywalking这类的APM应用是刚需。
ES 索引概括和地址
用ES来存储Skywalking数据,每天会生成114个索引,这个不是动态的哟,而是官方定义好的,当然你也可以自己根据需要做其他兼容,这个另说了。114个索引中,分成五大模块,约十个小模块,今天咱们都具体说说每个模块都有哪些索引(注意:本文说到的是Skywalking-aop的8.3.0版本,其他版本可能有细微差别)。
那如何来寻找这些索引呢,很简单。
1、直接页面内查找,这种方式很简单,其实页面第一个banner仪表盘中的图表,每一个都会是一个或多个索引,注意不是一对一或者唯一的哟,因为一个索引可能存在与多个图表上,至于如何寻找,可以看左上角的那个小锁,点一下就有惊喜。
2、直接在页面上看,也只能看到索引名,那每个名字什么意思,或者如何计算呢,可以直接看官方配置文件。
启动OAP服务(本文统一都是用DOCKER来启动的,启动过程可以看我之前写的《微服务组件记事本:本地搭建Skywalking》文章),启动后,进入容器,然后在config文件夹下会看到一个oal的文件夹。
进入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相关。
浏览器模块:browser.oal(33)
我们查看下browser.oal文件,可以看到很多的索引名称和计算方式,咱们分成2个子模块来说,打开Skywalking-ui看到仪表盘-WebBrowser栏目下,有两个子模块,分别是Web APP指标和Pages指标:
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);
核心服务模块:core.oal(38)
服务相关的索引,基本都是在仪表盘-APM和Database菜单里,而在APM栏目里又有四个子栏目,因此分成五个部分。分别是全局指标、服务间指标、服务实例指标、终端指标、数据库指标。
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);
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();
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();
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个索引主要是这些。
其他索引(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试试哟。
点击【阅读原文】,查看更多持久化方案👇