Add Grafana to master-slave monitoring stack
Feature: Issue 12619
Change-Id: Ia1e64e39d192402ec329b0497591f3be34503d5b
diff --git a/master-slave/Makefile b/master-slave/Makefile
index 90b60e4..aa87fc3 100644
--- a/master-slave/Makefile
+++ b/master-slave/Makefile
@@ -22,7 +22,9 @@
--stack-name $(CLUSTER_STACK_NAME) \
--capabilities CAPABILITY_IAM \
--template-body file://`pwd`/$(CLUSTER_TEMPLATE) \
- --region $(AWS_REGION)
+ --region $(AWS_REGION) \
+ --parameters \
+ ParameterKey=DesiredCapacity,ParameterValue=$(CLUSTER_DESIRED_CAPACITY)
service-master:
$(AWS_FC_COMMAND) create-stack \
@@ -154,5 +156,8 @@
prometheus-publish:
$(MAKE) -C ../monitoring/prometheus prometheus-publish RECIPE=master-slave
+grafana-publish:
+ $(MAKE) -C ../monitoring/grafana grafana-publish RECIPE=master-slave
+
service-monitoring:
$(MAKE) -C ../monitoring service-monitoring RECIPE=master-slave
diff --git a/master-slave/README.md b/master-slave/README.md
index 4dcff58..6b5baa5 100644
--- a/master-slave/README.md
+++ b/master-slave/README.md
@@ -73,6 +73,11 @@
* `HOSTED_ZONE_NAME`: Optional. Name of the hosted zone. `mycompany.com` by default.
* `MASTER_SUBDOMAIN`: Optional. Name of the master sub domain. `gerrit-master-demo` by default.
* `SLAVE_SUBDOMAIN`: Optional. Name of the slave sub domain. `gerrit-slave-demo` by default.
+* `CLUSTER_DESIRED_CAPACITY`: Optional. Number of EC2 instances composing the cluster. `1` by default.
+
+*NOTE: if you are planning to run the monitoring stack, set the
+`CLUSTER_DESIRED_CAPACITY` value to at least 2. The resources provided by
+a single EC2 instance won't be enough for all the services that will be ran*
### Prerequisites
diff --git a/master-slave/setup.env.template b/master-slave/setup.env.template
index 30fee20..eb20cf5 100644
--- a/master-slave/setup.env.template
+++ b/master-slave/setup.env.template
@@ -1,13 +1,16 @@
CLUSTER_STACK_NAME:=gerrit-cluster
+CLUSTER_DESIRED_CAPACITY:=1
SERVICE_MASTER_STACK_NAME:=gerrit-service-master
SERVICE_SLAVE_STACK_NAME:=gerrit-service-slave
SERVICE_PROMETHEUS_STACK_NAME:=gerrit-prometheus
+SERVICE_GRAFANA_STACK_NAME:=gerrit-grafana
DNS_ROUTING_STACK_NAME:=gerrit-dns-routing
DNS_ROUTING_MONITORING_STACK_NAME:=gerrit-monitoring-dns-routing
HOSTED_ZONE_NAME:=yourcompany.com
MASTER_SUBDOMAIN:=gerrit-master.gerrit-demo
SLAVE_SUBDOMAIN:=gerrit-slave.gerrit-demo
PROMETHEUS_SUBDOMAIN:=gerrit-prometheus.gerrit-demo
+GRAFANA_SUBDOMAIN:=gerrit-grafana.gerrit-demo
AWS_REGION:=us-east-1
DOCKER_REGISTRY_URI:=<yourAccountId>.dkr.ecr.us-east-1.amazonaws.com
SSL_CERTIFICATE_ARN=arn:aws:acm:us-east-1:<yourAccountId>:certificate/33e2c235-a4d1-42b7-b866-18d8d744975c
diff --git a/monitoring/Makefile b/monitoring/Makefile
index 3a77cc9..f703011 100644
--- a/monitoring/Makefile
+++ b/monitoring/Makefile
@@ -2,9 +2,11 @@
AWS_FC_COMMAND=export AWS_PAGER=;aws cloudformation
SERVICE_PROMETHEUS_TEMPLATE:=cf-service-prometheus.yml
+SERVICE_GRAFANA_TEMPLATE:=cf-service-grafana.yml
DNS_ROUTING_MONITORING_TEMPLATE:=cf-dns-route.yml
service-monitoring: service-prometheus wait-for-service-prometheus-creation \
+ service-grafana wait-for-service-grafana-creation \
dns-monitoring-routing wait-for-dns-routing-creation
service-prometheus:
@@ -22,6 +24,23 @@
ParameterKey=CertificateArn,ParameterValue=$(SSL_CERTIFICATE_ARN) \
ParameterKey=TokenVersion,ParameterValue=$(TOKEN_VERSION)
+service-grafana:
+ @echo "Create Grafana stack"
+ $(AWS_FC_COMMAND) create-stack \
+ --stack-name $(SERVICE_GRAFANA_STACK_NAME) \
+ --capabilities CAPABILITY_IAM \
+ --template-body file://`pwd`/$(SERVICE_GRAFANA_TEMPLATE) \
+ --region $(AWS_REGION) \
+ --parameters \
+ ParameterKey=ClusterStackName,ParameterValue=$(CLUSTER_STACK_NAME) \
+ ParameterKey=PrometheusStackName,ParameterValue=$(SERVICE_PROMETHEUS_STACK_NAME) \
+ ParameterKey=MasterStackName,ParameterValue=$(SERVICE_MASTER_STACK_NAME) \
+ ParameterKey=SlaveStackName,ParameterValue=$(SERVICE_SLAVE_STACK_NAME) \
+ ParameterKey=HostedZoneName,ParameterValue=$(HOSTED_ZONE_NAME) \
+ ParameterKey=Subdomain,ParameterValue=$(GRAFANA_SUBDOMAIN) \
+ ParameterKey=DockerRegistryUrl,ParameterValue=$(DOCKER_REGISTRY_URI) \
+ ParameterKey=CertificateArn,ParameterValue=$(SSL_CERTIFICATE_ARN)
+
dns-monitoring-routing:
$(AWS_FC_COMMAND) create-stack \
--stack-name $(DNS_ROUTING_MONITORING_STACK_NAME) \
@@ -29,7 +48,8 @@
--template-body file://`pwd`/$(DNS_ROUTING_MONITORING_TEMPLATE) \
--region $(AWS_REGION) \
--parameters \
- ParameterKey=PrometheusServiceStackName,ParameterValue=$(SERVICE_PROMETHEUS_STACK_NAME)
+ ParameterKey=PrometheusServiceStackName,ParameterValue=$(SERVICE_PROMETHEUS_STACK_NAME) \
+ ParameterKey=GrafanaServiceStackName,ParameterValue=$(SERVICE_GRAFANA_STACK_NAME)
wait-for-service-prometheus-creation:
@echo "*** Wait for Serice Prometheus stack '$(SERVICE_PROMETHEUS_STACK_NAME)' creation"
@@ -38,6 +58,13 @@
--region $(AWS_REGION)
@echo "*** Serice Prometheus stack '$(SERVICE_PROMETHEUS_STACK_NAME)' created"
+wait-for-service-grafana-creation:
+ @echo "*** Wait for Serice Grafana stack '$(SERVICE_GRAFANA_STACK_NAME)' creation"
+ $(AWS_FC_COMMAND) wait stack-create-complete \
+ --stack-name $(SERVICE_GRAFANA_STACK_NAME) \
+ --region $(AWS_REGION)
+ @echo "*** Serice Prometheus stack '$(SERVICE_GRAFANA_STACK_NAME)' created"
+
wait-for-dns-routing-creation:
@echo "*** Wait for DNS routing stack '$(DNS_ROUTING_MONITORING_STACK_NAME)' creation"
$(AWS_FC_COMMAND) wait stack-create-complete \
diff --git a/monitoring/README.md b/monitoring/README.md
index a5f3051..e9e098c 100644
--- a/monitoring/README.md
+++ b/monitoring/README.md
@@ -15,6 +15,13 @@
* From the main cookbook, publish the image: `make prometheus-publish`
+### Publish custom Grafana Docker image
+
+* Create the repository in the Docker registry:
+ `aws ecr create-repository --repository-name aws-gerrit/grafana`
+
+* From the main cookbook, publish the image: `make grafana-publish`
+
### Import a Prometheus Bearer Token
* [Generate](https://www.uuidgenerator.net/) a Token
@@ -46,3 +53,19 @@
| grep OutputValue \
| cut -d'"' -f 4
```
+
+### Access your Grafana instance
+
+Get the URL of your Prometheus instance this way:
+
+```
+aws cloudformation describe-stacks \
+ --stack-name <SERVICE_PROMETHEUS_STACK_NAME> \
+ | grep -A1 '"OutputKey": "CanonicalWebUrl"' \
+ | grep OutputValue \
+ | cut -d'"' -f 4
+```
+
+The default credentials are:
+* user `admin`
+* password `admin`
diff --git a/monitoring/cf-dns-route.yml b/monitoring/cf-dns-route.yml
index 2292e0e..36dc0ed 100644
--- a/monitoring/cf-dns-route.yml
+++ b/monitoring/cf-dns-route.yml
@@ -5,6 +5,10 @@
Description: Stack name of the ECS Prometheus service
Type: String
Default: gerrit-prometheus
+ GrafanaServiceStackName:
+ Description: Stack name of the ECS Grafana service
+ Type: String
+ Default: gerrit-grafana
Resources:
PrometheusDnsRecord:
@@ -20,7 +24,7 @@
- ''
- - Fn::ImportValue: !Join [':', [!Ref 'PrometheusServiceStackName', 'HostedZoneName']]
- '.'
- Comment: DNS name for Gerrit Master.
+ Comment: DNS name for Prometheus.
Type: A
AliasTarget:
DNSName:
@@ -30,3 +34,26 @@
Fn::ImportValue:
!Join [':', [!Ref 'PrometheusServiceStackName', 'CanonicalHostedZoneID']]
EvaluateTargetHealth: False
+ GrafanaDnsRecord:
+ Type: AWS::Route53::RecordSet
+ Properties:
+ Name:
+ !Join
+ - '.'
+ - - Fn::ImportValue: !Join [':', [!Ref 'GrafanaServiceStackName', 'Subdomain']]
+ - Fn::ImportValue: !Join [':', [!Ref 'GrafanaServiceStackName', 'HostedZoneName']]
+ HostedZoneName:
+ !Join
+ - ''
+ - - Fn::ImportValue: !Join [':', [!Ref 'GrafanaServiceStackName', 'HostedZoneName']]
+ - '.'
+ Comment: DNS name for Grafana.
+ Type: A
+ AliasTarget:
+ DNSName:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'GrafanaServiceStackName', 'PublicLoadBalancerDNSName']]
+ HostedZoneId:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'GrafanaServiceStackName', 'CanonicalHostedZoneID']]
+ EvaluateTargetHealth: False
diff --git a/monitoring/cf-service-grafana.yml b/monitoring/cf-service-grafana.yml
new file mode 100644
index 0000000..a159f6f
--- /dev/null
+++ b/monitoring/cf-service-grafana.yml
@@ -0,0 +1,215 @@
+ AWSTemplateFormatVersion: '2010-09-09'
+ Description: Deploy a Grafana service into an ECS cluster behind a public load balancer.
+ Parameters:
+ GrafanaServiceName:
+ Type: String
+ Default: gerrit-grafana
+ PrometheusStackName:
+ Type: String
+ Default: gerrit-prometheus
+ MasterStackName:
+ Type: String
+ Default: gerrit-master
+ SlaveStackName:
+ Type: String
+ Default: gerrit-slave
+ ClusterStackName:
+ Description: Stack name of the ECS cluster to deploy the serivces
+ Type: String
+ Default: gerrit-cluster
+ EnvironmentName:
+ Description: An environment name that will be prefixed to the resource names
+ Type: String
+ Default: test
+ DockerImage:
+ Description: Grafana official Docker image
+ Type: String
+ Default: aws-gerrit/grafana:latest
+ DockerRegistryUrl:
+ Description: Docker registry URL
+ Type: String
+ DesiredCount:
+ Description: How many instances of this task should we run across our cluster?
+ Type: Number
+ Default: 1
+ HTTPPort:
+ Description: Grafana HTTP port
+ Type: Number
+ Default: 3000
+ HTTPSPort:
+ Description: Grafana HTTPS port
+ Type: Number
+ Default: 443
+ CertificateArn:
+ Description: SSL Certificates ARN
+ Type: String
+ HostedZoneName:
+ Description: The route53 HostedZoneName.
+ Type: String
+ Subdomain:
+ Description: The subdomain of the Monitoring service
+ Type: String
+ Default: gerrit-grafana
+
+ Resources:
+ Service:
+ Type: AWS::ECS::Service
+ DependsOn:
+ - HTTPListener
+ Properties:
+ Cluster:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'ClusterStackName', 'ClusterName']]
+ DesiredCount: !Ref DesiredCount
+ TaskDefinition: !Ref TaskDefinition
+ LoadBalancers:
+ - ContainerName: !Ref GrafanaServiceName
+ ContainerPort: !Ref HTTPPort
+ TargetGroupArn: !Ref HTTPTargetGroup
+
+ TaskDefinition:
+ Type: AWS::ECS::TaskDefinition
+ Properties:
+ Family: !Join ['', [!Ref GrafanaServiceName, TaskDefinition]]
+ TaskRoleArn: !Ref ECSTaskExecutionRole
+ ExecutionRoleArn: !Ref ECSTaskExecutionRole
+ NetworkMode: bridge
+ ContainerDefinitions:
+ - Name: !Ref GrafanaServiceName
+ Essential: true
+ Image: !Sub '${DockerRegistryUrl}/${DockerImage}'
+ Environment:
+ - Name: AWS_REGION
+ Value: !Ref AWS::Region
+ - Name: GRAFANA_DOMAIN
+ Value: !Sub '${Subdomain}.${HostedZoneName}'
+ - Name: MASTER_URL
+ Value:
+ !Join
+ - '.'
+ - - Fn::ImportValue: !Join [':', [!Ref 'MasterStackName', 'Subdomain']]
+ - Fn::ImportValue: !Join [':', [!Ref 'MasterStackName', 'HostedZoneName']]
+ - Name: SLAVE_URL
+ Value:
+ !Join
+ - '.'
+ - - Fn::ImportValue: !Join [':', [!Ref 'SlaveStackName', 'Subdomain']]
+ - Fn::ImportValue: !Join [':', [!Ref 'SlaveStackName', 'HostedZoneName']]
+ - Name: PROMETHEUS_URL
+ Value:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'PrometheusStackName', 'CanonicalWebUrl']]
+ Cpu: 1024
+ Memory: 2048
+ PortMappings:
+ - ContainerPort: !Ref HTTPPort
+ HostPort: !Ref HTTPPort
+ Protocol: tcp
+ LogConfiguration:
+ LogDriver: awslogs
+ Options:
+ awslogs-group: !Ref ClusterStackName
+ awslogs-region: !Ref AWS::Region
+ awslogs-stream-prefix: !Ref EnvironmentName
+
+ LoadBalancer:
+ Type: AWS::ElasticLoadBalancingV2::LoadBalancer
+ Properties:
+ Type: network
+ Scheme: internet-facing
+ Subnets:
+ - Fn::ImportValue:
+ !Join [':', [!Ref 'ClusterStackName', 'PublicSubnetOne']]
+ Tags:
+ - Key: Name
+ Value: !Join ['-', [!Ref 'EnvironmentName', !Ref 'GrafanaServiceName', 'monitoring']]
+
+ HTTPTargetGroup:
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ DependsOn: LoadBalancer
+ Properties:
+ VpcId:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'ClusterStackName', 'VPCId']]
+ Port: !Ref HTTPPort
+ Protocol: TCP
+
+ HTTPListener:
+ Type: AWS::ElasticLoadBalancingV2::Listener
+ DependsOn: LoadBalancer
+ Properties:
+ Certificates:
+ - CertificateArn: !Ref CertificateArn
+ DefaultActions:
+ - Type: forward
+ TargetGroupArn: !Ref HTTPTargetGroup
+ LoadBalancerArn: !Ref LoadBalancer
+ Port: !Ref HTTPSPort
+ Protocol: TLS
+
+ # This is a role which is used by the ECS tasks themselves.
+ ECSTaskExecutionRole:
+ Type: AWS::IAM::Role
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Effect: Allow
+ Principal:
+ Service: [ecs-tasks.amazonaws.com]
+ Action: ['sts:AssumeRole']
+ Path: /
+ Policies:
+ - PolicyName: AmazonECSTaskExecutionRolePolicy
+ PolicyDocument:
+ Statement:
+ - Effect: Allow
+ Action:
+ # Allow the ECS Tasks to download images from ECR
+ - 'ecr:GetAuthorizationToken'
+ - 'ecr:BatchCheckLayerAvailability'
+ - 'ecr:GetDownloadUrlForLayer'
+ - 'ecr:BatchGetImage'
+ # Allow the ECS tasks to upload logs to CloudWatch
+ - 'logs:CreateLogStream'
+ - 'logs:PutLogEvents'
+ Resource: '*'
+ - PolicyName: AmazonECSTaskSecretManagerRolePolicy
+ PolicyDocument:
+ Statement:
+ - Effect: Allow
+ Action:
+ # Allow the ECS Tasks to get SSH Keys
+ - 'secretsmanager:GetSecretValue'
+ - 'kms:Decrypt'
+ Resource: '*'
+ Outputs:
+ PublicLoadBalancerDNSName:
+ Description: The DNS name of the external load balancer
+ Value: !GetAtt 'LoadBalancer.DNSName'
+ Export:
+ Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicLoadBalancerDNSName' ] ]
+ CanonicalHostedZoneID:
+ Description: Canonical Hosted Zone ID
+ Value: !GetAtt 'LoadBalancer.CanonicalHostedZoneID'
+ Export:
+ Name: !Join [ ':', [ !Ref 'AWS::StackName', 'CanonicalHostedZoneID' ] ]
+ PublicLoadBalancerUrl:
+ Description: The url of the external load balancer
+ Value: !Join ['', ['http://', !GetAtt 'LoadBalancer.DNSName']]
+ Export:
+ Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicLoadBalancerUrl' ] ]
+ HostedZoneName:
+ Description: Route53 Hosted Zone name
+ Value: !Ref HostedZoneName
+ Export:
+ Name: !Join [ ':', [ !Ref 'AWS::StackName', 'HostedZoneName' ] ]
+ Subdomain:
+ Description: Service DNS subdomain
+ Value: !Ref Subdomain
+ Export:
+ Name: !Join [ ':', [ !Ref 'AWS::StackName', 'Subdomain' ] ]
+ CanonicalWebUrl:
+ Description: Canonical Web URL
+ Value: !Sub 'https://${Subdomain}.${HostedZoneName}'
+ Export:
+ Name: !Join [ ':', [ !Ref 'AWS::StackName', 'CanonicalWebUrl' ] ]
diff --git a/monitoring/grafana/Dockerfile b/monitoring/grafana/Dockerfile
new file mode 100644
index 0000000..cae1df8
--- /dev/null
+++ b/monitoring/grafana/Dockerfile
@@ -0,0 +1,13 @@
+FROM grafana/grafana:6.7.0
+
+USER root
+ADD ./provisioning /etc/grafana/provisioning
+ADD ./config.ini /etc/grafana/config.ini
+ADD ./dashboards /var/lib/grafana/dashboards
+COPY --chown=grafana:grafana entrypoint.sh /entrypoint.sh
+RUN chown -R grafana:grafana /etc/grafana && \
+ chown -R grafana:grafana /var/lib/grafana && \
+ chmod +x /entrypoint.sh
+
+USER grafana
+ENTRYPOINT /entrypoint.sh
diff --git a/monitoring/grafana/Makefile b/monitoring/grafana/Makefile
new file mode 100644
index 0000000..e613e81
--- /dev/null
+++ b/monitoring/grafana/Makefile
@@ -0,0 +1,12 @@
+include ../../$(RECIPE)/setup.env
+
+docker-registry-login:
+ aws ecr get-login-password --region $(AWS_REGION) \
+ | docker login --username AWS --password-stdin $(DOCKER_REGISTRY_URI)/aws-gerrit/grafana
+
+grafana-build:
+ docker build -t aws-gerrit/grafana .
+ docker tag aws-gerrit/grafana:latest $(DOCKER_REGISTRY_URI)/aws-gerrit/grafana:latest
+
+grafana-publish: docker-registry-login grafana-build
+ docker push $(DOCKER_REGISTRY_URI)/aws-gerrit/grafana:latest
diff --git a/monitoring/grafana/config.ini b/monitoring/grafana/config.ini
new file mode 100644
index 0000000..9ee0efe
--- /dev/null
+++ b/monitoring/grafana/config.ini
@@ -0,0 +1,9 @@
+[paths]
+provisioning = /etc/grafana/provisioning
+
+[server]
+enable_gzip = true
+domain = {{DOMAIN}}
+
+[users]
+default_theme = light
diff --git a/monitoring/grafana/dashboards/Gerrit.json b/monitoring/grafana/dashboards/Gerrit.json
new file mode 100644
index 0000000..45d41e4
--- /dev/null
+++ b/monitoring/grafana/dashboards/Gerrit.json
@@ -0,0 +1,2047 @@
+{
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": "-- Grafana --",
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "type": "dashboard"
+ }
+ ]
+ },
+ "description": "Metrics dashboard for Gerrit multi-site",
+ "editable": true,
+ "gnetId": 4496,
+ "graphTooltip": 0,
+ "id": 1,
+ "iteration": 1587574303643,
+ "links": [],
+ "panels": [
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "#299c46",
+ "rgba(237, 129, 40, 0.89)",
+ "#d44a3a"
+ ],
+ "datasource": "Prometheus",
+ "decimals": 0,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": true,
+ "thresholdLabels": false,
+ "thresholdMarkers": false
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 6,
+ "x": 0,
+ "y": 0
+ },
+ "id": 92,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "max_over_time(sshd_sessions_connected{instance=\"{{MASTER_URL}}:443\"}[$Window])",
+ "format": "time_series",
+ "instant": true,
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "thresholds": "30,60",
+ "title": "SSH Conn master",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "0",
+ "value": "null"
+ }
+ ],
+ "valueName": "avg"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "#299c46",
+ "rgba(237, 129, 40, 0.89)",
+ "#d44a3a"
+ ],
+ "datasource": "Prometheus",
+ "decimals": 0,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": true,
+ "thresholdLabels": false,
+ "thresholdMarkers": false
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 6,
+ "x": 6,
+ "y": 0
+ },
+ "id": 94,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "env",
+ "targets": [
+ {
+ "expr": "max_over_time(sshd_sessions_connected{instance=\"{{SLAVE_URL}}:443\"}[$Window])",
+ "format": "time_series",
+ "instant": true,
+ "intervalFactor": 1,
+ "refId": "A"
+ }
+ ],
+ "thresholds": "30,60",
+ "title": "SSH Conn slave",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "0",
+ "value": "null"
+ }
+ ],
+ "valueName": "avg"
+ },
+ {
+ "collapsed": false,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 8
+ },
+ "id": 100,
+ "panels": [],
+ "title": "Live Status",
+ "type": "row"
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "system cpu load",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 10,
+ "w": 8,
+ "x": 0,
+ "y": 9
+ },
+ "hiddenSeries": false,
+ "id": 3,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "avg_over_time(javamelody_system_cpu_load_pct[$Window])",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "30s",
+ "intervalFactor": 2,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "% Cpu Load",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "decimals": null,
+ "format": "percent",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "used memory for JGit cache in bytes",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 10,
+ "w": 8,
+ "x": 8,
+ "y": 9
+ },
+ "hiddenSeries": false,
+ "id": 146,
+ "interval": "1s",
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "review-1-javamelody",
+ "yaxis": 1
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "avg_over_time(jgit_block_cache_cache_used[$Window])",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "10s",
+ "intervalFactor": 1,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "JGit Cache",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "decbytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": false
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "used memory in bytes",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 10,
+ "w": 8,
+ "x": 16,
+ "y": 9
+ },
+ "hiddenSeries": false,
+ "id": 12,
+ "interval": "1s",
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "review-1-javamelody",
+ "yaxis": 1
+ }
+ ],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "avg_over_time(javamelody_memory_used_bytes[$Window])",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "10s",
+ "intervalFactor": 1,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "Used Memory",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "decbytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": false
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 10,
+ "w": 8,
+ "x": 0,
+ "y": 19
+ },
+ "hiddenSeries": false,
+ "id": 118,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": false,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "delta(http_server_error_count_500_total[$Window])",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "HTTP 500",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "decimals": null,
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 10,
+ "w": 8,
+ "x": 8,
+ "y": 19
+ },
+ "hiddenSeries": false,
+ "id": 116,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": false,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "delta(sshd_sessions_authentication_failures_total[$Window])",
+ "format": "time_series",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "SSH Authentication Failures",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "collapsed": false,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 29
+ },
+ "id": 72,
+ "panels": [],
+ "repeat": null,
+ "title": "System Resources",
+ "type": "row"
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "system load average",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 12,
+ "x": 0,
+ "y": 30
+ },
+ "hiddenSeries": false,
+ "id": 1,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "avg_over_time(javamelody_system_load_avg[$Window])",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "1m",
+ "intervalFactor": 1,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "System Load",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "gc time",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 12,
+ "x": 12,
+ "y": 30
+ },
+ "hiddenSeries": false,
+ "id": 14,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "rate(javamelody_memory_gc_millis[$Window])",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "10s",
+ "intervalFactor": 1,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "GC Time",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "active thread count",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 12,
+ "x": 0,
+ "y": 39
+ },
+ "hiddenSeries": false,
+ "id": 16,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "avg_over_time(javamelody_threads_active_count[$Window])",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "",
+ "intervalFactor": 1,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "Active Threads",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "unix open file descriptors count",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 12,
+ "x": 12,
+ "y": 39
+ },
+ "hiddenSeries": false,
+ "id": 6,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "avg_over_time(javamelody_system_unix_file_descriptors_open_count[$Window])",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "30s",
+ "intervalFactor": 2,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "Unix File Descriptors Open Count",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "collapsed": false,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 48
+ },
+ "id": 76,
+ "panels": [],
+ "repeat": null,
+ "title": "HTTP",
+ "type": "row"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 8,
+ "x": 0,
+ "y": 49
+ },
+ "hiddenSeries": false,
+ "id": 96,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "rightSide": false,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "delta(javamelody_http_duration_millis[$Window])/delta(javamelody_http_hits_count[$Window])",
+ "format": "time_series",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "HTTP requests mean time",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 8,
+ "x": 8,
+ "y": 49
+ },
+ "hiddenSeries": false,
+ "id": 51,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "delta(javamelody_http_hits_count[$Window])",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "30s",
+ "intervalFactor": 2,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "HTTP hits per minute",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "opm",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": false
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {
+ "review-1-javamelody": "#5195ce",
+ "review-2-javamelody": "#7eb26d"
+ },
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "description": "",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 8,
+ "x": 16,
+ "y": 49
+ },
+ "hiddenSeries": false,
+ "id": 52,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": true,
+ "min": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "application": {
+ "filter": ""
+ },
+ "expr": "delta(javamelody_http_errors_count[$Window])/delta(javamelody_http_hits_count[$Window])*100",
+ "format": "time_series",
+ "functions": [],
+ "group": {
+ "filter": ""
+ },
+ "host": {
+ "filter": ""
+ },
+ "instant": false,
+ "interval": "30s",
+ "intervalFactor": 2,
+ "item": {
+ "filter": ""
+ },
+ "legendFormat": "{{instance}}",
+ "mode": 0,
+ "options": {
+ "showDisabledItems": false
+ },
+ "refId": "A",
+ "triggers": {
+ "acknowledged": 2,
+ "count": true,
+ "minSeverity": 3
+ }
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "% of HTTP Errors",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "decimals": null,
+ "format": "percent",
+ "label": null,
+ "logBase": 1,
+ "max": "100",
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "collapsed": false,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 58
+ },
+ "id": 126,
+ "panels": [],
+ "title": "Git",
+ "type": "row"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 12,
+ "x": 0,
+ "y": 59
+ },
+ "hiddenSeries": false,
+ "id": 124,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": false,
+ "max": true,
+ "min": true,
+ "rightSide": false,
+ "show": true,
+ "total": true,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "increase(git_upload_pack_request_count_total_total[$Window])",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}} Tot git upload pack",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "Git upload pack - count",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 9,
+ "w": 12,
+ "x": 12,
+ "y": 59
+ },
+ "hiddenSeries": false,
+ "id": 128,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": false,
+ "max": true,
+ "min": true,
+ "rightSide": false,
+ "show": true,
+ "total": true,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "increase(git_upload_pack_request_count_CLONE_total[$Window])",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}} Tot Clone",
+ "refId": "B"
+ },
+ {
+ "expr": "increase(git_upload_pack_request_count_FETCH_total[$Window])",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}} Tot Fetch",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "Git clone and fetch count",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ },
+ {
+ "collapsed": false,
+ "datasource": null,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 68
+ },
+ "id": 114,
+ "panels": [],
+ "title": "Queues",
+ "type": "row"
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "Prometheus",
+ "fill": 1,
+ "fillGradient": 0,
+ "gridPos": {
+ "h": 8,
+ "w": 24,
+ "x": 0,
+ "y": 69
+ },
+ "hiddenSeries": false,
+ "id": 112,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "options": {
+ "dataLinks": []
+ },
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "delta(queue_index_batch_total_scheduled_tasks_count[$Window])",
+ "format": "time_series",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}} Index",
+ "refId": "A"
+ },
+ {
+ "expr": "delta(queue_receive_commits_total_scheduled_tasks_count[$Window])",
+ "format": "time_series",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}} Receive Commits",
+ "refId": "B"
+ },
+ {
+ "expr": "delta(queue_work_queue_total_scheduled_tasks_count[$Window])",
+ "format": "time_series",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}} Tasks",
+ "refId": "C"
+ },
+ {
+ "expr": "delta(queue_ssh_command_start_total_scheduled_tasks_count[$Window])",
+ "format": "time_series",
+ "intervalFactor": 1,
+ "legendFormat": "{{instance}} SSH Command start",
+ "refId": "D"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeRegions": [],
+ "timeShift": null,
+ "title": "Scheduled Tasks Queues",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ],
+ "yaxis": {
+ "align": false,
+ "alignLevel": null
+ }
+ }
+ ],
+ "refresh": false,
+ "schemaVersion": 22,
+ "style": "dark",
+ "tags": [
+ "prometheus"
+ ],
+ "templating": {
+ "list": [
+ {
+ "allValue": null,
+ "current": {
+ "isNone": true,
+ "selected": false,
+ "text": "None",
+ "value": ""
+ },
+ "datasource": "Prometheus",
+ "definition": "",
+ "hide": 0,
+ "includeAll": false,
+ "index": -1,
+ "label": "Application",
+ "multi": false,
+ "name": "Application",
+ "options": [],
+ "query": "javamelody_system_load_avg",
+ "refresh": 2,
+ "regex": "/{alias=\"(.*)\",instance/",
+ "skipUrlSync": false,
+ "sort": 0,
+ "tagValuesQuery": "",
+ "tags": [],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ },
+ {
+ "auto": false,
+ "auto_count": 30,
+ "auto_min": "10s",
+ "current": {
+ "selected": false,
+ "text": "1m",
+ "value": "1m"
+ },
+ "hide": 0,
+ "label": "Aggregation window",
+ "name": "Window",
+ "options": [
+ {
+ "selected": true,
+ "text": "1m",
+ "value": "1m"
+ },
+ {
+ "selected": false,
+ "text": "5m",
+ "value": "5m"
+ },
+ {
+ "selected": false,
+ "text": "10m",
+ "value": "10m"
+ },
+ {
+ "selected": false,
+ "text": "30m",
+ "value": "30m"
+ },
+ {
+ "selected": false,
+ "text": "1h",
+ "value": "1h"
+ }
+ ],
+ "query": "1m,5m,10m,30m,1h",
+ "refresh": 2,
+ "skipUrlSync": false,
+ "type": "interval"
+ }
+ ]
+ },
+ "time": {
+ "from": "2020-04-21T05:35:35.287Z",
+ "to": "2020-04-21T12:11:11.551Z"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "browser",
+ "title": "Gerrit",
+ "uid": "VfddQL5mk",
+ "variables": {
+ "list": []
+ },
+ "version": 1
+}
diff --git a/monitoring/grafana/entrypoint.sh b/monitoring/grafana/entrypoint.sh
new file mode 100644
index 0000000..a474d2a
--- /dev/null
+++ b/monitoring/grafana/entrypoint.sh
@@ -0,0 +1,9 @@
+#!/bin/bash -e
+
+echo "Updating Grafana templates..."
+sed -i -e "s|{{DOMAIN}}|$GRAFANA_DOMAIN|g" /etc/grafana/config.ini
+sed -i -e "s|{{PROMETHEUS_URL}}|$PROMETHEUS_URL|g" /etc/grafana/provisioning/datasources/prometheus.yml
+sed -i -e "s|{{MASTER_URL}}|$MASTER_URL|g" /var/lib/grafana/dashboards/Gerrit.json
+sed -i -e "s|{{SLAVE_URL}}|$SLAVE_URL|g" /var/lib/grafana/dashboards/Gerrit.json
+
+/run.sh
diff --git a/monitoring/grafana/provisioning/dashboards/gerrit.yml b/monitoring/grafana/provisioning/dashboards/gerrit.yml
new file mode 100644
index 0000000..abc1adc
--- /dev/null
+++ b/monitoring/grafana/provisioning/dashboards/gerrit.yml
@@ -0,0 +1,11 @@
+# # config file version
+apiVersion: 1
+
+providers:
+- name: 'Gerrit'
+ orgId: 1
+ folder: ''
+ folderUid: ''
+ type: file
+ options:
+ path: /var/lib/grafana/dashboards
diff --git a/monitoring/grafana/provisioning/datasources/prometheus.yml b/monitoring/grafana/provisioning/datasources/prometheus.yml
new file mode 100644
index 0000000..f4c6037
--- /dev/null
+++ b/monitoring/grafana/provisioning/datasources/prometheus.yml
@@ -0,0 +1,50 @@
+# config file version
+apiVersion: 1
+
+# list of datasources that should be deleted from the database
+deleteDatasources:
+ - name: Prometheus
+ orgId: 1
+
+# list of datasources to insert/update depending
+# whats available in the database
+datasources:
+ # <string, required> name of the datasource. Required
+- name: Prometheus
+ # <string, required> datasource type. Required
+ type: prometheus
+ # <string, required> access mode. direct or proxy. Required
+ access: proxy
+ # <int> org id. will default to orgId 1 if not specified
+ orgId: 1
+ # <string> url
+ url: {{PROMETHEUS_URL}}
+ # <string> database password, if used
+ password:
+ # <string> database user, if used
+ user:
+ # <string> database name, if used
+ database:
+ # <bool> enable/disable basic auth
+ basicAuth: false
+ # <string> basic auth username, if used
+ basicAuthUser:
+ # <string> basic auth password, if used
+ basicAuthPassword:
+ # <bool> enable/disable with credentials headers
+ withCredentials:
+ # <bool> mark as default datasource. Max one per org
+ isDefault: true
+ # <map> fields that will be converted to json and stored in json_data
+ jsonData:
+ graphiteVersion: "1.1"
+ tlsAuth: false
+ tlsAuthWithCACert: false
+ # <string> json object of data that will be encrypted.
+ secureJsonData:
+ tlsCACert: "..."
+ tlsClientCert: "..."
+ tlsClientKey: "..."
+ version: 1
+ # <bool> allow users to edit datasources from the UI.
+ editable: true