blob: 2df2b4f940d2a7632460b5c44beff4b374b4c454 [file] [log] [blame]
<!doctype html>
<!--
Minimal Mistakes Jekyll Theme 4.4.1 by Michael Rose
Copyright 2017 Michael Rose - mademistakes.com | @mmistakes
Free for personal and commercial use under the MIT license
https://github.com/mmistakes/minimal-mistakes/blob/master/LICENSE.txt
-->
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<!-- begin SEO -->
<title>Metrics in 1.0.0-m1 - Apache ServiceComb</title>
<meta name="description" content="Metrics in 1.0.0-m1">
<meta name="author" content="">
<meta property="og:locale" content="en">
<meta property="og:site_name" content="Apache ServiceComb">
<meta property="og:title" content="Metrics in 1.0.0-m1">
<link rel="canonical" href="https://github.com/pages/apache/incubator-servicecomb-website/docs/users/metrics-in-1.0.0-m1/">
<meta property="og:url" content="https://github.com/pages/apache/incubator-servicecomb-website/docs/users/metrics-in-1.0.0-m1/">
<meta property="og:description" content="Metrics in 1.0.0-m1">
<meta name="twitter:site" content="@ServiceComb">
<meta name="twitter:title" content="Metrics in 1.0.0-m1">
<meta name="twitter:description" content="Metrics in 1.0.0-m1">
<meta name="twitter:url" content="">
<meta name="twitter:card" content="summary">
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "Person",
"name" : "Apache ServiceComb",
"url" : "https://github.com/pages/apache/incubator-servicecomb-website",
"sameAs" : null
}
</script>
<meta name="google-site-verification" content="HvJjNd7vvJ-yjSTHlBiIWEYxp_Hrz-PYEY5Idz9LRcA" />
<!-- end SEO -->
<link href="/feed.xml" type="application/atom+xml" rel="alternate" title="Apache ServiceComb Feed">
<!-- http://t.co/dKP3o1e -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/g, '') + ' js ';
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
<script src="/assets/vendor/prism/prism.js"></script>
<script type="text/javascript" async
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<script src="https://www.apachecon.com/event-images/snippet.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
<!-- For all browsers -->
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="stylesheet" href="/assets/vendor/prism/prism.css">
<!--[if lte IE 9]>
<style>
/* old IE unsupported flexbox fixes */
.greedy-nav .site-title {
padding-right: 3em;
}
.greedy-nav button {
position: absolute;
top: 0;
right: 0;
height: 100%;
}
</style>
<![endif]-->
<meta http-equiv="cleartype" content="on">
<!-- start custom head snippets -->
<!-- insert favicons. use http://realfavicongenerator.net/ -->
<link href="https://fonts.loli.net/css?family=Roboto:400,500,700|Source+Code+Pro" rel="stylesheet">
<script src="/assets/js/custom.js"></script>
<!-- end custom head snippets -->
</head>
<body class="layout--single">
<!--[if lt IE 9]>
<div class="notice--danger align-center" style="margin: 0;">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</div>
<![endif]-->
<div class="masthead" onmouseleave="$('#childrenShow').css('display', 'none')">
<div class="masthead__inner-wrap">
<div class="masthead__menu">
<nav id="site-nav" class="greedy-nav">
<a class="site-title active" href="/"><img src="https://www.apache.org/img/servicecomb.png"></a>
<ul class="visible-links">
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/">Home</a>
</li>
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/developers/">Projects</a>
</li>
<li class="def-nav-li" onmouseenter="$('#childrenShow').css('display', 'block')">
<a class="active" href="/docs/users/">Documentation</a>
<ul id="childrenShow" class="def-children-show-en" onmouseleave="$('#childrenShow').css('display', 'none')">
<li><a href="/docs/getting-started/" class="">Getting started</a></li>
<li><a href="/docs/users/" class="">Docs</a></li>
<li><a href="/slides/" class="">Video</a></li>
<li><a href="/faqs/" class="">FAQ</a></li>
</ul>
</li>
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/year-archive/">Blogs</a>
</li>
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/release/">Downloads</a>
</li>
</ul>
<button><div class="navicon"></div></button>
<ul class="hidden-links hidden"></ul>
<div class="nav-lang">
<a href=/cn/docs/users/metrics-in-1.0.0-m1/>中文</a>
</div>
</nav>
</div>
</div>
</div>
<div id="main" role="main">
<div class="sidebar sticky">
<div class="back-to-home"><a href="/">Home</a> > Metrics in 1.0.0-m1</div>
<nav class="nav__list">
<input id="ac-toc" name="accordion-toc" type="checkbox" />
<label for="ac-toc">Toggle Menu</label>
<ul class="nav__items">
<li>
<span class="nav__sub-title">Java Chassis User Guide</span>
<ul>
<li><a href="/references/java-chassis/zh_CN/index.html" class="">Java Chassis 3</a></li>
<li><a href="/references/java-chassis/2.x/zh_CN/index.html" class="">Java Chassis 2</a></li>
</ul>
</li>
<li>
<span class="nav__sub-title">Pack User Guide</span>
<ul>
<li><a href="https://github.com/apache/servicecomb-pack/blob/master/docs/user_guide.md" class="">0.5.0</a></li>
</ul>
</li>
<li>
<span class="nav__sub-title">ServiceCenter User Guide</span>
<ul>
<li><a href="https://service-center.readthedocs.io/en/latest/user-guides.html" class="">2.0.0</a></li>
</ul>
</li>
<li>
<span class="nav__sub-title">Kie User Guide</span>
<ul>
<li><a href="https://kie.readthedocs.io/en/latest/" class="">0.2.0</a></li>
</ul>
</li>
<li>
<span class="nav__sub-title">Mesher User Guide</span>
<ul>
<li><a href="https://mesher.readthedocs.io/en/latest/" class="">1.6.3</a></li>
</ul>
</li>
</ul>
</nav>
</div>
<article class="page" itemscope itemtype="http://schema.org/CreativeWork">
<meta itemprop="headline" content="Metrics in 1.0.0-m1">
<meta itemprop="description" content="Metrics in 1.0.0-m1">
<meta itemprop="dateModified" content="December 30, 2017">
<div class="page__inner-wrap">
<header>
<h1 class="page__title" itemprop="headline">Metrics in 1.0.0-m1
</h1>
</header>
<section class="page__content" itemprop="text">
<aside class="sidebar__right">
<nav class="toc">
<!-- <header><h4 class="nav__title"><i class="fa fa-file-text"></i> On This Page</h4></header> -->
<ul class="toc__menu" id="markdown-toc">
<li><a href="#background" id="markdown-toc-background">Background</a></li>
<li><a href="#1000-m1-principles" id="markdown-toc-1000-m1-principles">1.0.00-m1 Principles</a> <ul>
<li><a href="#use-event-collect-invocation-datanot-from-hystrixhandler-bizkeeperany-more" id="markdown-toc-use-event-collect-invocation-datanot-from-hystrixhandler-bizkeeperany-more">Use event collect invocation data,not from Hystrix(handler-bizkeeper)any more</a></li>
<li><a href="#use-netflix-servo-as-monitor-of-metric" id="markdown-toc-use-netflix-servo-as-monitor-of-metric">Use Netflix Servo as Monitor of Metric</a></li>
<li><a href="#window-timealso-may-called-polling-interval-or-step-cycle" id="markdown-toc-window-timealso-may-called-polling-interval-or-step-cycle">Window Time(also may called ‘Polling Interval’ or ‘Step Cycle’)</a></li>
</ul>
</li>
<li><a href="#metrics-id-format" id="markdown-toc-metrics-id-format">Metrics ID Format</a> <ul>
<li><a href="#jvm-information" id="markdown-toc-jvm-information">JVM Information</a></li>
<li><a href="#invocation-information" id="markdown-toc-invocation-information">Invocation Information</a></li>
</ul>
</li>
<li><a href="#how-to-configuration" id="markdown-toc-how-to-configuration">How to Configuration</a> <ul>
<li><a href="#global-configuration" id="markdown-toc-global-configuration">Global Configuration</a></li>
<li><a href="#maven-configuration" id="markdown-toc-maven-configuration">Maven Configuration</a></li>
</ul>
</li>
<li><a href="#how-to-get-metrics-data" id="markdown-toc-how-to-get-metrics-data">How to Get Metrics Data</a> <ul>
<li><a href="#embedded-publish-interface" id="markdown-toc-embedded-publish-interface">Embedded publish interface</a></li>
<li><a href="#direct-programming-get" id="markdown-toc-direct-programming-get">Direct programming get</a></li>
</ul>
</li>
<li><a href="#how-to-use-metrics-data" id="markdown-toc-how-to-use-metrics-data">How to Use Metrics Data</a></li>
<li><a href="#how-to-extend-custom-metrics" id="markdown-toc-how-to-extend-custom-metrics">How to Extend Custom Metrics</a></li>
<li><a href="#other-reference" id="markdown-toc-other-reference">Other Reference</a></li>
</ul>
</nav>
</aside>
<p>Metrics had supported from Java chassis version 0.5.0,in version 1.0.0-m1,we had reconstruction it and add some more features,please checkout the user guide and <a href="https://github.com/apache/servicecomb-java-chassis/releases">release note</a> for more information.Also subscribe ServiceComb mail-list(dev-subscribe@servicecomb.apache.org) and join discussion is welcome.</p>
<h2 id="background">Background</h2>
<p>Microservice is trend of technology,it resolve many problems also follows new problem.</p>
<p><img src="/assets/images/MonolithicArch.png" alt="MonolithicArch" /></p>
<p>This is traditional software architecture always called ‘Monolithic’,it’s difficult for developer maintain the code or add new feature because of tight coupling,but it’s easy for operation engineer deploy and maintenance(only one system process).</p>
<p><img src="/assets/images/MicroserviceArch.png" alt="MicroserviceArch" /></p>
<p>This is microservice system architecture,after split ‘Monolithic’ into many small services,developer obtain many benefits such as architecture independent and more agility etc,but operation engineer need to maintenance a whole lot of microservice instances.If don’t import metrics,when system is abnormal or user experience getting worse,it’s very difficult to dentifying where the problem is and make some strategy in order to prevent it.</p>
<h2 id="1000-m1-principles">1.0.00-m1 Principles</h2>
<p>In previous version(0.5.0),implementation of metrics had some imperfections:</p>
<ol>
<li>Metrics code written in foundation-metrics module,it’s a low level module,and include some customized function;</li>
<li>Use ThreadLocal variable collect and statistics data,performance hight but has memory leak risk;</li>
<li>Output data of metrics is joined text not dependent number,difficult to reuse;</li>
<li>Not support publish,unable integration with other monitor system;</li>
<li>Because foundation-metrics is a low level module and certainly be loaded,user can’t exclude it if unnecessary.</li>
</ol>
<p>So,upgrading from 0.5.0 to 1.0.0-m1,we had done a fully reconstruction,now it’s include this modules:</p>
<table>
<thead>
<tr>
<th style="text-align: left">Module Name</th>
<th style="text-align: left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">foundation-metrics</td>
<td style="text-align: left">Metrics mechanism module</td>
</tr>
<tr>
<td style="text-align: left">metrics-core</td>
<td style="text-align: left">Metrics core module,work immediately after imported</td>
</tr>
<tr>
<td style="text-align: left">metrics-integration</td>
<td style="text-align: left">Include metrics Integration with other monitor system</td>
</tr>
</tbody>
</table>
<p>The dependency of this modules is:</p>
<p><img src="/assets/images/MetricsDependency.png" alt="MetricsDependency.png" /></p>
<h3 id="use-event-collect-invocation-datanot-from-hystrixhandler-bizkeeperany-more">Use event collect invocation data,not from Hystrix(handler-bizkeeper)any more</h3>
<p>From 1.0.0-m1 invocation data such as TPS and latency are collected from invocation event,not from Hystrix(handler-bizkeeper) any more,so you don’t need add Java Chassis Bizkeeper Handler only for metrics.we use EventBus in foundation-common,when EventBus had initialized,three build-in event listener class will be auto registered via SPI(Service Provider Interface):</p>
<table>
<thead>
<tr>
<th style="text-align: left">Event Listener Name</th>
<th style="text-align: left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">InvocationStartedEventListener</td>
<td style="text-align: left">Process InvocationStartedEvent when consumer or producer called</td>
</tr>
<tr>
<td style="text-align: left">InvocationStartExecutionEventListener</td>
<td style="text-align: left">Process InvocationStartExecutionEvent when producer fetch invocation from queue and start process</td>
</tr>
<tr>
<td style="text-align: left">InvocationFinishedEventListener</td>
<td style="text-align: left">Process InvocationFinishedEvent when consumer call returned or producer process finished</td>
</tr>
</tbody>
</table>
<p><em>ServiceComb java chassis had used <a href="http://vertx.io/">Vertx</a> as Reactor framework,in synchronous call mode when producer received invocation from consumer,it won’t start process immediately but put it into a queue,this queue called invocation queue(like disk queue in operation system),time waiting in the queue called <strong>LifeTimeInQueue</strong>,the length of the queue called <strong>waitInQueue</strong>,this two metrics are very important for measure stress of the microservice;consumer not has this queue,so InvocationStartProcessingEvent will never be triggered at consumer side.</em></p>
<p>The code for trigger event write in RestInvocation,HighwayServerInvoke and InvokerUtils,if microservice don’t import metrics,event listeners of metrics won’t be registered,the impact on performance is little.</p>
<h3 id="use-netflix-servo-as-monitor-of-metric">Use Netflix Servo as Monitor of Metric</h3>
<p><a href="https://github.com/Netflix/servo">Netflix Servo</a> had implement a collection of high performance monitor,we had used five of them:</p>
<table>
<thead>
<tr>
<th style="text-align: left">Monitor Name</th>
<th style="text-align: left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">BasicCounter</td>
<td style="text-align: left">As name of it,always increment</td>
</tr>
<tr>
<td style="text-align: left">StepCounter</td>
<td style="text-align: left">Called ‘ResettableCounter’ before</td>
</tr>
<tr>
<td style="text-align: left">BasicTimer</td>
<td style="text-align: left">Time (Latency) monitor</td>
</tr>
<tr>
<td style="text-align: left">BasicGauge</td>
<td style="text-align: left">Return a Callable call result monitor</td>
</tr>
<tr>
<td style="text-align: left">MaxGauge</td>
<td style="text-align: left">Mark max value in step</td>
</tr>
</tbody>
</table>
<p><em>The version of Servo we used is 0.10.1</em></p>
<h3 id="window-timealso-may-called-polling-interval-or-step-cycle">Window Time(also may called ‘Polling Interval’ or ‘Step Cycle’)</h3>
<p>Metrics had many classifications,we can divided them into two major types by how get value:</p>
<ol>
<li>Direct get<br />
You can direct get newest value anytime,such as system resource usage include cpu load rate,running thread count,heap size and call count,queue length,etc.</li>
<li>From statistics<br />
After a ‘certain time’ passed can counting the value,this time we called ‘Window Time’,include:<br />
a) Take one from many,like Max、Min、Median; <br />
b) Time-related,like TPS(transaction per second); <br />
c) Count-related,like average,variance. <br />
If get value of this type,the result returned is the last ‘Step Cycle’ counted.in Servo,this time called <a href="https://github.com/Netflix/servo/wiki/Getting-Started">‘Polling Intervals’</a>.
From 1.0.0-m1,can set <strong>servicecomb.metrics.window_time</strong> in microservice.yaml,it has same effect as set <strong>servo.pollers</strong>.</li>
</ol>
<p><strong>Notice: Servo had marked with DEPRECATED by Netflix, we will use Netflix spectator instead in 1.0.0-m2, no need to set the window_time any more</strong></p>
<h2 id="metrics-id-format">Metrics ID Format</h2>
<p>From 1.0.0-m1,build-in two type Metric output:</p>
<h3 id="jvm-information">JVM Information</h3>
<p>ID format is : <em>jvm(statistic=gauge,name={name})</em>
name include:</p>
<table>
<thead>
<tr>
<th style="text-align: left">Name</th>
<th style="text-align: left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">cpuLoad</td>
<td style="text-align: left">CPU load rate</td>
</tr>
<tr>
<td style="text-align: left">cpuRunningThreads</td>
<td style="text-align: left">Running thread count</td>
</tr>
<tr>
<td style="text-align: left">heapInit,heapMax,heapCommit,heapUsed</td>
<td style="text-align: left">Memory heap usage</td>
</tr>
<tr>
<td style="text-align: left">nonHeapInit,nonHeapMax,nonHeapCommit,nonHeapUsed</td>
<td style="text-align: left">Memory nonHeap usage</td>
</tr>
</tbody>
</table>
<h3 id="invocation-information">Invocation Information</h3>
<p>ID format is : <em>servicecomb.invocation(operation={operationName},role={role},stage={stage},statistic={statistic},status={status},unit={unit})</em>
Tag name and value below:</p>
<table>
<thead>
<tr>
<th style="text-align: left">Tag Name</th>
<th style="text-align: left">Description</th>
<th style="text-align: left">Options or Values</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">operationName</td>
<td style="text-align: left">Operation full name</td>
<td style="text-align: left">MicroserviceQualifiedName</td>
</tr>
<tr>
<td style="text-align: left">role</td>
<td style="text-align: left">Consumer side or Producer side</td>
<td style="text-align: left">consume,producer</td>
</tr>
<tr>
<td style="text-align: left">stage</td>
<td style="text-align: left">Stage of metrics</td>
<td style="text-align: left">queue(producer only),execution(producer only,total</td>
</tr>
<tr>
<td style="text-align: left">statistic</td>
<td style="text-align: left">Normally metric type</td>
<td style="text-align: left">tps,count(total call count),max,waitInQueue(producer),latency</td>
</tr>
<tr>
<td style="text-align: left">status</td>
<td style="text-align: left">Call result code</td>
<td style="text-align: left">200, 404 etc..</td>
</tr>
<tr>
<td style="text-align: left">unit</td>
<td style="text-align: left">TimeUint of latency</td>
<td style="text-align: left">MILLISECONDS,SECONDS etc..</td>
</tr>
</tbody>
</table>
<h2 id="how-to-configuration">How to Configuration</h2>
<h3 id="global-configuration">Global Configuration</h3>
<p>Please add window time config in microservice.yaml:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">APPLICATION_ID</span><span class="pi">:</span> <span class="s">demo</span>
<span class="na">service_description</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">demoService</span>
<span class="na">version</span><span class="pi">:</span> <span class="s">0.0.1</span>
<span class="na">servicecomb</span><span class="pi">:</span>
<span class="na">metrics</span><span class="pi">:</span>
<span class="c1">#window time,same as servo.pollers,unit is millisecond,default value is 5000 (5 seconds)</span>
<span class="na">window_time</span><span class="pi">:</span> <span class="m">5000</span>
</code></pre></div></div>
<p><strong>In order to decrease difficulty for understand and usage of metrics,we temporary do not support multi window time</strong></p>
<h3 id="maven-configuration">Maven Configuration</h3>
<p>We just only need add metrics-core dependency:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nt">&lt;dependency&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.servicecomb<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>metrics-core<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>1.0.0-m1<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>
<h2 id="how-to-get-metrics-data">How to Get Metrics Data</h2>
<p>After configuration completed,you can get collected metrics data via this two method:</p>
<h3 id="embedded-publish-interface">Embedded publish interface</h3>
<p>When microservice start-up,metrics-core will auto publish data service using Springmvc provider:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestSchema</span><span class="o">(</span><span class="n">schemaId</span> <span class="o">=</span> <span class="s">"metricsEndpoint"</span><span class="o">)</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="n">path</span> <span class="o">=</span> <span class="s">"/metrics"</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MetricsPublisher</span> <span class="o">{</span>
<span class="nd">@ApiResponses</span><span class="o">({</span>
<span class="nd">@ApiResponse</span><span class="o">(</span><span class="n">code</span> <span class="o">=</span> <span class="mi">400</span><span class="o">,</span> <span class="n">response</span> <span class="o">=</span> <span class="nc">String</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="n">message</span> <span class="o">=</span> <span class="s">"illegal request content"</span><span class="o">),</span>
<span class="o">})</span>
<span class="nd">@RequestMapping</span><span class="o">(</span><span class="n">path</span> <span class="o">=</span> <span class="s">"/"</span><span class="o">,</span> <span class="n">method</span> <span class="o">=</span> <span class="nc">RequestMethod</span><span class="o">.</span><span class="na">GET</span><span class="o">)</span>
<span class="nd">@CrossOrigin</span>
<span class="kd">public</span> <span class="nc">Map</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Double</span><span class="o">&gt;</span> <span class="nf">measure</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="nc">MonitorManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">measure</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>So,if you had config rest provider in microservice.yaml,like:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">servicecomb</span><span class="pi">:</span>
<span class="na">service</span><span class="pi">:</span>
<span class="na">registry</span><span class="pi">:</span>
<span class="na">address</span><span class="pi">:</span> <span class="s">http://127.0.0.1:30100</span>
<span class="na">rest</span><span class="pi">:</span>
<span class="na">address</span><span class="pi">:</span> <span class="s">0.0.0.0:8080</span>
</code></pre></div></div>
<p>You can open a browser and input http://localhost:8080/metrics direct get metrics data.</p>
<h3 id="direct-programming-get">Direct programming get</h3>
<p>From above code you can known,the entry of data provider is org.apache.servicecomb.metrics.core.MonitorManager,so if you want develop your own metrics publisher,direct get it is enough.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">MonitorManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="nc">MonitorManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span>
<span class="nc">Map</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Double</span><span class="o">&gt;</span> <span class="n">metrics</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">measure</span><span class="o">();</span>
</code></pre></div></div>
<p><strong>Notice: Servo had marked with DEPRECATED by Netflix, we will use Netflix spectator instead in 1.0.0-m2, publish interface will be adjusted</strong></p>
<h2 id="how-to-use-metrics-data">How to Use Metrics Data</h2>
<p>Metrics data will output as Map&lt;String,Double&gt;,in order to let user easier fetch certain metric value,we provide org.apache.servicecomb.foundation.metrics.publish.MetricsLoader tool class:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c1">//simulate MonitorManager.getInstance().measure() get all metrics data</span>
<span class="nc">Map</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Double</span><span class="o">&gt;</span> <span class="n">metrics</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HashMap</span><span class="o">&lt;&gt;();</span>
<span class="n">metrics</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"X(K1=1,K2=2,K3=3)"</span><span class="o">,</span> <span class="mf">100.0</span><span class="o">);</span>
<span class="n">metrics</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"X(K1=1,K2=20,K3=30)"</span><span class="o">,</span> <span class="mf">200.0</span><span class="o">);</span>
<span class="n">metrics</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"X(K1=2,K2=200,K3=300)"</span><span class="o">,</span> <span class="mf">300.0</span><span class="o">);</span>
<span class="n">metrics</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"X(K1=2,K2=2000,K3=3000)"</span><span class="o">,</span> <span class="mf">400.0</span><span class="o">);</span>
<span class="n">metrics</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"Y(K1=1,K2=2,K3=3)"</span><span class="o">,</span> <span class="mf">500.0</span><span class="o">);</span>
<span class="n">metrics</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"Y(K1=10,K2=20,K3=30)"</span><span class="o">,</span> <span class="mf">600.0</span><span class="o">);</span>
<span class="n">metrics</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"Y(K1=100,K2=200,K3=300)"</span><span class="o">,</span> <span class="mf">700.0</span><span class="o">);</span>
<span class="n">metrics</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"Y(K1=1000,K2=2000,K3=3000)"</span><span class="o">,</span> <span class="mf">800.0</span><span class="o">);</span>
<span class="c1">//new MetricsLoader load all metrics data</span>
<span class="nc">MetricsLoader</span> <span class="n">loader</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MetricsLoader</span><span class="o">(</span><span class="n">metrics</span><span class="o">);</span>
<span class="c1">//get name of 'X' Metrics then group by K1,K2</span>
<span class="nc">MetricNode</span> <span class="n">node</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="na">getMetricTree</span><span class="o">(</span><span class="s">"X"</span><span class="o">,</span><span class="s">"K1"</span><span class="o">,</span><span class="s">"K2"</span><span class="o">);</span>
<span class="c1">//get all Metrics of K1=1 and K2=20</span>
<span class="n">node</span><span class="o">.</span><span class="na">getChildrenNode</span><span class="o">(</span><span class="s">"1"</span><span class="o">).</span><span class="na">getChildrenNode</span><span class="o">(</span><span class="s">"20"</span><span class="o">).</span><span class="na">getMetrics</span><span class="o">();</span>
<span class="c1">//get K3=30 Metric from node</span>
<span class="n">node</span><span class="o">.</span><span class="na">getChildrenNode</span><span class="o">(</span><span class="s">"1"</span><span class="o">).</span><span class="na">getChildrenNode</span><span class="o">(</span><span class="s">"20"</span><span class="o">).</span><span class="na">getFirstMatchMetricValue</span><span class="o">(</span><span class="s">"K3"</span><span class="o">,</span><span class="s">"30"</span><span class="o">);</span>
</code></pre></div></div>
<p><em>More detail can be found in demo/perf/PerfMetricsFilePublisher.java</em></p>
<h2 id="how-to-extend-custom-metrics">How to Extend Custom Metrics</h2>
<p>Java Chassis Metrics support user extend custom metrics,MonitorManager had a set of method get different type of Monitor:</p>
<table>
<thead>
<tr>
<th style="text-align: left">Method Name</th>
<th style="text-align: left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">getCounter</td>
<td style="text-align: left">Get a counter monitor</td>
</tr>
<tr>
<td style="text-align: left">getMaxGauge</td>
<td style="text-align: left">Get a max monitor</td>
</tr>
<tr>
<td style="text-align: left">getGauge</td>
<td style="text-align: left">Get a gauge monitor</td>
</tr>
<tr>
<td style="text-align: left">getTimer</td>
<td style="text-align: left">Get a timer monitor</td>
</tr>
</tbody>
</table>
<p>Let us use Process Order make an example:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">OrderController</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">Counter</span> <span class="n">orderCount</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">Counter</span> <span class="n">orderTps</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">Timer</span> <span class="n">averageLatency</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">MaxGauge</span> <span class="n">maxLatency</span><span class="o">;</span>
<span class="nc">OrderController</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">MonitorManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="nc">MonitorManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span>
<span class="c1">//"product","levis jeans" and "model","512" are two custom Tag,support multi Tags</span>
<span class="k">this</span><span class="o">.</span><span class="na">orderCount</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getCounter</span><span class="o">(</span><span class="s">"orderCount"</span><span class="o">,</span> <span class="s">"product"</span><span class="o">,</span> <span class="s">"levis jeans"</span><span class="o">,</span> <span class="s">"model"</span><span class="o">,</span> <span class="s">"512"</span><span class="o">);</span>
<span class="k">this</span><span class="o">.</span><span class="na">orderTps</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getCounter</span><span class="o">(</span><span class="nl">StepCounter:</span><span class="o">:</span><span class="k">new</span><span class="o">,</span> <span class="s">"orderGenerated"</span><span class="o">,</span> <span class="s">"statistic"</span><span class="o">,</span> <span class="s">"tps"</span><span class="o">);</span>
<span class="k">this</span><span class="o">.</span><span class="na">averageLatency</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getTimer</span><span class="o">(</span><span class="s">"orderGenerated"</span><span class="o">,</span> <span class="s">"statistic"</span><span class="o">,</span> <span class="s">"latency"</span><span class="o">,</span> <span class="s">"unit"</span><span class="o">,</span> <span class="s">"MILLISECONDS"</span><span class="o">);</span>
<span class="k">this</span><span class="o">.</span><span class="na">maxLatency</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getMaxGauge</span><span class="o">(</span><span class="s">"orderGenerated"</span><span class="o">,</span> <span class="s">"statistic"</span><span class="o">,</span> <span class="s">"max"</span><span class="o">,</span> <span class="s">"unit"</span><span class="o">,</span> <span class="s">"MILLISECONDS"</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">makeOrder</span><span class="o">()</span> <span class="o">{</span>
<span class="kt">long</span> <span class="n">startTime</span> <span class="o">=</span> <span class="nc">System</span><span class="o">.</span><span class="na">nanoTime</span><span class="o">();</span>
<span class="c1">//process order logic</span>
<span class="c1">//...</span>
<span class="c1">//process finished</span>
<span class="kt">long</span> <span class="n">totalTime</span> <span class="o">=</span> <span class="nc">System</span><span class="o">.</span><span class="na">nanoTime</span><span class="o">()</span> <span class="o">-</span> <span class="n">startTime</span><span class="o">;</span>
<span class="c1">//increase order count</span>
<span class="k">this</span><span class="o">.</span><span class="na">orderCount</span><span class="o">.</span><span class="na">increment</span><span class="o">();</span>
<span class="c1">//increase tps</span>
<span class="k">this</span><span class="o">.</span><span class="na">orderTps</span><span class="o">.</span><span class="na">increment</span><span class="o">();</span>
<span class="c1">//record latency for average</span>
<span class="k">this</span><span class="o">.</span><span class="na">averageLatency</span><span class="o">.</span><span class="na">record</span><span class="o">(</span><span class="n">totalTime</span><span class="o">,</span> <span class="nc">TimeUnit</span><span class="o">.</span><span class="na">NANOSECONDS</span><span class="o">);</span>
<span class="c1">//record max latency</span>
<span class="k">this</span><span class="o">.</span><span class="na">maxLatency</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="nc">TimeUnit</span><span class="o">.</span><span class="na">NANOSECONDS</span><span class="o">.</span><span class="na">toMillis</span><span class="o">(</span><span class="n">totalTime</span><span class="o">));</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Notice:</p>
<p>1.Metric ID is join name and all tags that pass to MonitorManager when getting monitor,so please keep uniqueness,metrics output of front example are:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Map</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span><span class="nc">Double</span><span class="o">&gt;</span> <span class="n">metrics</span> <span class="o">=</span> <span class="nc">MonitorManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">measure</span><span class="o">();</span>
<span class="c1">//metrics.keySet() include:</span>
<span class="c1">// orderCount(product=levis jeans,model=512)</span>
<span class="c1">// orderGenerated(statistic=tps)</span>
<span class="c1">// orderGenerated(statistic=latency,unit=MILLISECONDS)</span>
<span class="c1">// orderGenerated(statistic=max,unit=MILLISECONDS)</span>
</code></pre></div></div>
<p>2.All get monitor method in MonitorManager act as <strong>get or new</strong>,so use same name and tags will return same one monitor:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Counter</span> <span class="n">counter1</span> <span class="o">=</span> <span class="nc">MonitorManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">getCounter</span><span class="o">(</span><span class="s">"orderGenerated"</span><span class="o">,</span> <span class="s">"product"</span><span class="o">,</span> <span class="s">"levis jeans"</span><span class="o">,</span> <span class="s">"model"</span><span class="o">,</span> <span class="s">"512"</span><span class="o">);</span>
<span class="nc">Counter</span> <span class="n">counter2</span> <span class="o">=</span> <span class="nc">MonitorManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">getCounter</span><span class="o">(</span><span class="s">"orderGenerated"</span><span class="o">,</span> <span class="s">"product"</span><span class="o">,</span> <span class="s">"levis jeans"</span><span class="o">,</span> <span class="s">"model"</span><span class="o">,</span> <span class="s">"512"</span><span class="o">);</span>
<span class="n">counter1</span><span class="o">.</span><span class="na">increment</span><span class="o">();</span>
<span class="n">counter2</span><span class="o">.</span><span class="na">increment</span><span class="o">();</span>
<span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span><span class="n">counter1</span><span class="o">.</span><span class="na">getValue</span><span class="o">());</span>
<span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span><span class="n">counter2</span><span class="o">.</span><span class="na">getValue</span><span class="o">());</span>
<span class="nc">Assert</span><span class="o">.</span><span class="na">assertEquals</span><span class="o">(</span><span class="mf">2.0</span><span class="o">,</span><span class="nc">MonitorManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">measure</span><span class="o">().</span><span class="na">get</span><span class="o">(</span><span class="s">"orderGenerated(product=levis jeans,model=512)"</span><span class="o">),</span><span class="mi">0</span><span class="o">);</span>
</code></pre></div></div>
<p><strong>Performance of get monitor from MonitorManager is slightly lower,so please get all monitors what needed when init,then cache them for later use,like OrderController example.</strong></p>
<p><strong>Notice: Servo had marked with DEPRECATED by Netflix, we will use Netflix spectator instead in 1.0.0-m2, the way of extending custom metrics will be adjusted</strong></p>
<h2 id="other-reference">Other Reference</h2>
<p>We had developed two use case for reference:</p>
<ol>
<li>demo/perf:print Metrics in Console;</li>
<li>metrics-prometheus:integration with prometheus,publish metrics as prometheus producer.</li>
</ol>
</section>
<footer class="page__meta">
</footer>
</div>
</article>
</div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<div align="center" style="margin: 0 0;">
<ins class="adsbygoogle"
style="display:block; border-bottom: initial;"
data-ad-client="ca-pub-7328585512091257"
data-ad-slot="3049671934"
data-ad-format="auto"></ins>
</div>
<div class="page__footer">
<footer>
<!-- start custom footer snippets -->
<!-- end custom footer snippets -->
<div class="container">
<div class="row justify-content-md-center">
<div class="col">
<ul>
<p class="header">Events</p>
<a class="acevent" data-format="square" data-mode="dark" data-event="random"></a>
</ul>
</div>
<div class="col">
<ul>
<p class="header">Resources</p>
<li><a href="/docs/getting-started/">Getting started</a></li>
<li><a href="/docs/users/">User Guide</a></li>
<li><a href="/slides/">Slides</a></li>
<li><a href="/users/faq/">Common Questions</a></li>
</ul>
</div>
<div class="col">
<ul>
<p class="header">ASF</p>
<li><a href="http://www.apache.org">Foundation</a></li>
<li><a href="http://www.apache.org/licenses/">License</a></li>
<li><a href="http://www.apache.org/events/current-event">Events</a></li>
<li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
</ul>
</div>
<div class="col">
<ul>
<p class="header">Contribute</p>
<li><a href="http://issues.apache.org/jira/browse/SCB">Report a Doc Issue</a></li>
<li><a href="https://github.com/apache/servicecomb-website/edit/master/_users/metrics-in-1.0.0-m1.md">Edit This Page on Github</a></li>
<li><a href="/developers/submit-codes/">Code Submit Guide</a></li>
<li><a href="/security">Security</a></li>
</ul>
</div>
<div class="col">
<ul class="social-icons">
<p class="header">Community</p>
<li>
<a href="mailto:dev-subscribe@servicecomb.incubator.apache.org" rel="nofollow"><span class="mail">Mailing List</span></a>
</li>
<li>
<a href="https://github.com/apache?q=ServiceComb" target="_blank"><span class="github">Github</span></a>
</li>
<li>
<a href="https://twitter.com/ServiceComb" target="_blank"><span class="twitter">Twitter</span></a>
</li>
<li>
<a href="/feed.xml" target="_blank"><span class="rss">Feed</span></a>
</li>
</ul>
</div>
</div>
</div>
<div class="page__footer-bottom">
<div>&copy; 2024 Apache ServiceComb. Powered by <a href="http://jekyllrb.com" rel="nofollow">Jekyll</a> &amp; <a href="https://mademistakes.com/work/minimal-mistakes-jekyll-theme/" rel="nofollow">Minimal Mistakes</a>.</div>
<div>All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div>
</div>
</footer>
</div>
<script src="/assets/js/main.min.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-101622733-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>