-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Add Prometheus exporter module for Sentinel metrics #3173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
ef3cd1a
for issue 3126,first version
karl-sy 161111b
for issue 3126,with custom params
karl-sy 0c5a0fc
for issue 3126,polish prometheus server
karl-sy efce0ba
for issue 3126,readme cr
karl-sy 0a418f4
for issue 3126,readme cr
karl-sy 2aa0bf7
for issue 3126,readme cr
karl-sy 69f0559
for issue 3126,polish collect logic
karl-sy 0e2ffaf
for issue 3126,set prom fetch port
karl-sy 38894ab
for issue 3126,polish README.md
karl-sy d4f6cff
for issue 3126,del blank lines in README.md
karl-sy 94454de
for issue 3126,format
karl-sy 184a2a5
for issue 3126,format appName with '-'
karl-sy 60384ff
for issue 3126,with metric type constants
karl-sy d25fb67
replace constants
karl-sy 31f503c
for issue 3126,with license header
karl-sy eff3248
Merge remote-tracking branch 'origin/master'
karl-sy 36c1a92
for issue 3126,add tips
karl-sy 30fbbad
for issue 3126,modify default port to 9092
karl-sy cf76a1c
for issue 3126,modify default port to 9092
karl-sy a1a1cc4
for issue 3126,modify default port to 9092
karl-sy 5bcfac2
for issue 3126,modify default port to 9092
karl-sy 149e17d
for issue 3126,modify default port to 9092
karl-sy e1243d1
for issue 3126,add note
karl-sy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
sentinel-extension/sentinel-prometheus-metric-exporter/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# Sentinel Prometheus Exporter | ||
|
||
Sentinel Prometheus Exporter is a module which provides the Sentinel metrics data for prometheus. | ||
|
||
You can integrate it into your Sentinel application, and then get the sentinel metrics in your prometheus. | ||
|
||
## How it works | ||
|
||
when the prometheus server collect the sentinel metrics,it get metrics from sentinel logs | ||
 | ||
|
||
## How to use | ||
|
||
To use Sentinel Prometheus Exporter, you should add the following dependency: | ||
|
||
### 1. add sentinel-prometheus-exporter | ||
|
||
```xml | ||
<dependency> | ||
<groupId>com.alibaba.csp</groupId> | ||
<artifactId>sentinel-prometheus-metric-exporter</artifactId> | ||
<version>x.y.z</version> | ||
</dependency> | ||
``` | ||
|
||
### 2. add prometheus dependency | ||
|
||
```xml | ||
<dependency> | ||
<groupId>io.prometheus</groupId> | ||
<artifactId>simpleclient</artifactId> | ||
<version>0.3.0</version> | ||
</dependency> | ||
``` | ||
|
||
```xml | ||
<dependency> | ||
<groupId>io.prometheus</groupId> | ||
<artifactId>simpleclient_httpserver</artifactId> | ||
<version>0.3.0</version> | ||
</dependency> | ||
``` | ||
|
||
### 3. set prometheus.yml with fetch config | ||
|
||
```yaml | ||
scrape_configs: | ||
- job_name: 'sentinelMetrics' | ||
static_configs: | ||
- targets: ['localhost:20001'] | ||
``` | ||
|
||
## Params for exporter | ||
|
||
you can set system params to control the exporter behavior | ||
|
||
### 1.csp.sentinel.prometheus.fetch.port | ||
|
||
the port for prometheus exporter,default 20001 | ||
|
||
### 2.csp.sentinel.prometheus.fetch.size | ||
|
||
the max fetch nums for prometheus exporter,in case the memory is not enough,default 1024 | ||
|
||
### 3.csp.sentinel.prometheus.fetch.delay | ||
|
||
the delay time for fetching , may be it is still do some statistics work according to the sliding window size when fetching, | ||
|
||
so need to set the delay time to insure the accuracy. | ||
|
||
unit: second | ||
|
||
default: 0 | ||
|
||
### 4.csp.sentinel.prometheus.fetch.identify | ||
|
||
set the resource which need to fetch,default null,fetch all resources | ||
|
||
### 5.csp.sentinel.prometheus.fetch.types | ||
|
||
the types need to fetch,such as passQps,concurrency | ||
|
||
format: "xx|xx|xx" | ||
|
||
default: "passQps|blockQps|exceptionQps|rt|concurrency" | ||
|
||
you can reset the types as you need to,exm: "passQps|rt|concurrency|occupiedPassQps" | ||
|
||
the type is same as the MetricNode class variables, with range: | ||
{"passQps","blockQps","successQps","exceptionQps","rt","occupiedPassQps","concurrency"} | ||
|
||
### 6.csp.sentinel.prometheus.app | ||
|
||
set the appName when do PromSQL | ||
|
||
## how it looks | ||
|
||
 |
42 changes: 42 additions & 0 deletions
42
sentinel-extension/sentinel-prometheus-metric-exporter/pom.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>com.alibaba.csp</groupId> | ||
<artifactId>sentinel-parent</artifactId> | ||
<version>2.0.0-alpha</version> | ||
<relativePath>../../pom.xml</relativePath> | ||
</parent> | ||
|
||
<artifactId>sentinel-prometheus-metric-exporter</artifactId> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.alibaba.csp</groupId> | ||
<artifactId>sentinel-core</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.prometheus</groupId> | ||
<artifactId>simpleclient</artifactId> | ||
<version>0.3.0</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.prometheus</groupId> | ||
<artifactId>simpleclient_httpserver</artifactId> | ||
<version>0.3.0</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
39 changes: 39 additions & 0 deletions
39
...-metric-exporter/src/main/java/com/alibaba/csp/sentinel/metric/prom/PromExporterInit.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.alibaba.csp.sentinel.metric.prom; | ||
LearningGp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* The{@link PromExporterInit} the InitFunc for prometheus exporter. | ||
* | ||
* @author karl-sy | ||
* @date 2023-07-13 21:15 | ||
* @since 2.0.0 | ||
*/ | ||
import com.alibaba.csp.sentinel.init.InitFunc; | ||
import com.alibaba.csp.sentinel.log.RecordLog; | ||
import com.alibaba.csp.sentinel.metric.prom.collector.SentinelCollector; | ||
import com.alibaba.csp.sentinel.metric.prom.config.PrometheusGlobalConfig; | ||
import io.prometheus.client.exporter.HTTPServer; | ||
|
||
public class PromExporterInit implements InitFunc { | ||
|
||
@Override | ||
public void init() throws Exception { | ||
HTTPServer server = null; | ||
try { | ||
new SentinelCollector().register(); | ||
// 开启http服务供prometheus调用 | ||
// 默认只提供一个接口 http://ip:port/metrics,返回所有指标 | ||
int promPort = PrometheusGlobalConfig.getPromFetchPort(); | ||
server = new HTTPServer(promPort); | ||
} catch (Throwable e) { | ||
RecordLog.warn("[PromExporterInit] failed to init prometheus exporter with exception:", e); | ||
} | ||
|
||
HTTPServer finalServer = server; | ||
Runtime.getRuntime().addShutdownHook(new Thread(() -> { | ||
if (finalServer != null) { | ||
finalServer.stop(); | ||
} | ||
})); | ||
} | ||
|
||
} |
110 changes: 110 additions & 0 deletions
110
...orter/src/main/java/com/alibaba/csp/sentinel/metric/prom/collector/SentinelCollector.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package com.alibaba.csp.sentinel.metric.prom.collector; | ||
LearningGp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* The{@link PromExporterInit} the Collector for prometheus exporter. | ||
* | ||
* @author karl-sy | ||
* @date 2023-07-13 21:15 | ||
* @since 2.0.0 | ||
*/ | ||
import com.alibaba.csp.sentinel.config.SentinelConfig; | ||
import com.alibaba.csp.sentinel.log.RecordLog; | ||
import com.alibaba.csp.sentinel.metric.prom.config.PrometheusGlobalConfig; | ||
import com.alibaba.csp.sentinel.metric.prom.types.GaugeMetricFamily; | ||
import com.alibaba.csp.sentinel.node.metric.MetricNode; | ||
import com.alibaba.csp.sentinel.node.metric.MetricSearcher; | ||
import com.alibaba.csp.sentinel.node.metric.MetricWriter; | ||
import com.alibaba.csp.sentinel.util.PidUtil; | ||
import io.prometheus.client.Collector; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
public class SentinelCollector extends Collector { | ||
|
||
private final Object lock = new Object(); | ||
|
||
private static final int ONE_SECOND = 1000; | ||
private static final String appName = PrometheusGlobalConfig.getPromFetchApp(); | ||
|
||
private static final String[] types = PrometheusGlobalConfig.getPromFetchTypes(); | ||
|
||
private static final String identify = PrometheusGlobalConfig.getPromFetchIdentify(); | ||
|
||
private static final int fetchSize = PrometheusGlobalConfig.getPromFetchSize(); | ||
|
||
private static final int delayTime = PrometheusGlobalConfig.getPromFetchDelayTime(); | ||
|
||
private volatile MetricSearcher searcher; | ||
|
||
private volatile Long lastFetchTime; | ||
|
||
@Override | ||
public List<MetricFamilySamples> collect() { | ||
if (searcher == null) { | ||
synchronized (lock) { | ||
if (searcher == null) { | ||
searcher = new MetricSearcher(MetricWriter.METRIC_BASE_DIR, | ||
MetricWriter.formMetricFileName(SentinelConfig.getAppName(), PidUtil.getPid())); | ||
} | ||
RecordLog.warn("[SentinelCollector] init sentinel metrics searcher with appName:{}", appName); | ||
lastFetchTime = System.currentTimeMillis() / ONE_SECOND * ONE_SECOND; | ||
} | ||
} | ||
|
||
List<MetricFamilySamples> list = new ArrayList<>(); | ||
|
||
long endTime = System.currentTimeMillis() / ONE_SECOND * ONE_SECOND - (long) delayTime * ONE_SECOND; | ||
try { | ||
List<MetricNode> nodes = searcher.findByTimeAndResource(lastFetchTime, endTime, identify); | ||
if(nodes == null){ | ||
return list; | ||
} | ||
if(nodes.size() > fetchSize){ | ||
nodes = nodes.subList(0,fetchSize); | ||
} | ||
GaugeMetricFamily metricFamily = new GaugeMetricFamily(appName, | ||
"sentinel_metrics", Arrays.asList("resource","classification","type")); | ||
for (MetricNode node : nodes) { | ||
long recordTime = node.getTimestamp(); | ||
for (String type : types) { | ||
double val = getTypeVal(node,type); | ||
metricFamily.addMetric(Arrays.asList(node.getResource(), String.valueOf(node.getClassification()),type), val,recordTime); | ||
} | ||
} | ||
list.add(metricFamily); | ||
} catch (Exception e) { | ||
RecordLog.warn("[SentinelCollector] failed to fetch sentinel metrics with exception:", e); | ||
}finally { | ||
lastFetchTime = endTime + ONE_SECOND; | ||
} | ||
|
||
return list; | ||
} | ||
|
||
public double getTypeVal(MetricNode node,String type){ | ||
if("passQps".equals(type)){ | ||
LearningGp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return node.getPassQps(); | ||
} | ||
if("blockQps".equals(type)){ | ||
return node.getBlockQps(); | ||
} | ||
if("successQps".equals(type)){ | ||
return node.getSuccessQps(); | ||
} | ||
if("exceptionQps".equals(type)){ | ||
return node.getExceptionQps(); | ||
} | ||
if("rt".equals(type)){ | ||
return node.getRt(); | ||
} | ||
if("occupiedPassQps".equals(type)){ | ||
return node.getOccupiedPassQps(); | ||
} | ||
if("concurrency".equals(type)){ | ||
return node.getConcurrency(); | ||
} | ||
return -1.0; | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
...ter/src/main/java/com/alibaba/csp/sentinel/metric/prom/config/PrometheusGlobalConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package com.alibaba.csp.sentinel.metric.prom.config; | ||
LearningGp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* The config for prometheus exporter. | ||
* | ||
* @author karl-sy | ||
* @date 2023-07-13 21:15 | ||
* @since 2.0.0 | ||
*/ | ||
import com.alibaba.csp.sentinel.config.SentinelConfig; | ||
import com.alibaba.csp.sentinel.util.StringUtil; | ||
|
||
public class PrometheusGlobalConfig { | ||
|
||
public static final String PROM_FETCH_PORT = "csp.sentinel.prometheus.fetch.port"; | ||
public static final String DEFAULT_PROM_FETCH_PORT = "20001"; | ||
|
||
public static final String PROM_FETCH_SIZE = "csp.sentinel.prometheus.fetch.size"; | ||
public static final String DEFAULT_PROM_FETCH_SIZE = "1024"; | ||
|
||
public static final String PROM_FETCH_DELAY = "csp.sentinel.prometheus.fetch.delay"; | ||
public static final String DEFAULT_PROM_FETCH_DELAY = "0"; | ||
|
||
public static final String PROM_FETCH_IDENTIFY = "csp.sentinel.prometheus.fetch.identify"; | ||
|
||
public static final String PROM_FETCH_TYPES = "csp.sentinel.prometheus.fetch.types"; | ||
public static final String DEFAULT_PROM_FETCH_TYPES = "passQps|blockQps|exceptionQps|rt|concurrency"; | ||
|
||
public static final String PROM_APP = "csp.sentinel.prometheus.app"; | ||
public static final String DEFAULT_PROM_APP = "SENTINEL_APP"; | ||
|
||
public static int getPromFetchPort() { | ||
String config = SentinelConfig.getConfig(PROM_FETCH_PORT); | ||
config = StringUtil.isNotBlank(config) ? config : DEFAULT_PROM_FETCH_PORT; | ||
return Integer.parseInt(config); | ||
} | ||
|
||
public static int getPromFetchSize() { | ||
String config = SentinelConfig.getConfig(PROM_FETCH_SIZE); | ||
config = StringUtil.isNotBlank(config) ? config : DEFAULT_PROM_FETCH_SIZE; | ||
return Integer.parseInt(config); | ||
} | ||
|
||
public static int getPromFetchDelayTime() { | ||
String config = SentinelConfig.getConfig(PROM_FETCH_DELAY); | ||
config = StringUtil.isNotBlank(config) ? config : DEFAULT_PROM_FETCH_DELAY; | ||
return Integer.parseInt(config); | ||
} | ||
|
||
public static String getPromFetchIdentify() { | ||
return SentinelConfig.getConfig(PROM_FETCH_IDENTIFY); | ||
} | ||
|
||
public static String[] getPromFetchTypes() { | ||
String config = SentinelConfig.getConfig(PROM_FETCH_TYPES); | ||
config = StringUtil.isNotBlank(config) ? config : DEFAULT_PROM_FETCH_TYPES; | ||
try { | ||
return config.split("\\|"); | ||
}catch (Throwable e){ | ||
return DEFAULT_PROM_FETCH_TYPES.split("\\|"); | ||
} | ||
} | ||
|
||
public static String getPromFetchApp() { | ||
String appName = SentinelConfig.getConfig(PROM_APP); | ||
if (appName == null) { | ||
appName = SentinelConfig.getAppName(); | ||
} | ||
|
||
if (appName == null) { | ||
appName = DEFAULT_PROM_APP; | ||
} | ||
appName = appName.replaceAll("\\.","_"); | ||
appName = appName.replaceAll("-","_"); | ||
return appName; | ||
} | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.