Atlassian Jira, Prometheus and Slack integration in 15 minutes

In this article I will show how to integrate Atlassian Jira, Prometheus and Slack.

I will create a Slack channel where the Prometheus alert manager will post alerts. Alerts will be triggered by metrics taken from Atlassian Jira.

I will run Jira and Prometheus in docker. I will use the Idalko Jira image.

Please, watch this video for this article. It will let you understand this article better.

Here is the file structure after we have created all files from this article:

- tutorial
  - jira
      docker-compose.yml
  - prometheus
      docker-compose.yml
    - data
      - alertmanager
        - config
            alertmanager.yml
      - prometheus
        - config
            rules.yml
            prometheus.yml

Run Jira

Create a docker-compose.yml file:

version: '3'
services:
  jira:
    image: idalko/atlassian-jira-software
    environment:
      - DISABLE_NOTIFICATIONS=TRUE
      - JIRA_ARGS=-Datlassian.plugins.enable.wait=300
      - JVM_MINIMUM_MEMORY=2G
      - JVM_MAXIMUM_MEMORY=4G
    volumes:
      - ./data:/opt/atlassian/jira/data
    ports:
      - 8080:8080
    restart: always

  jiradb:
    image: postgres:9.6
    environment:
      - POSTGRES_PASSWORD=secret
      - POSTGRES_USER=jira
      - POSTGRES_DB=jira
    volumes:
      - ./db:/var/lib/postgresql/data
    restart: always

Run this docker-compose.yml file:

docker-compose up

Install the Prometheus Exporter for Jira app.

Run Prometheus

Create a docker-compose.yml file:

version: '3'
services:
  prometheus:
    image: prom/prometheus:latest
    container_name: monitoring_prometheus
    restart: unless-stopped
    volumes:
      - ./data/prometheus/config:/etc/prometheus/
      - ./data/prometheus/data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    expose:
      - 9090
    ports:
      - 9090:9090
    links:
      - cadvisor:cadvisor
      - node-exporter:node-exporter
  
  node-exporter:
    image: prom/node-exporter:latest
    container_name: monitoring_node_exporter
    restart: unless-stopped
    ports:
      - 9100:9100
    expose:
      - 9100
  
  cadvisor:
    image: google/cadvisor:latest
    container_name: monitoring_cadvisor
    restart: unless-stopped
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    ports:
      - 8081:8080
    expose:
      - 8080

  alertmanager:
    image: prom/alertmanager:latest
    volumes:
      - ./data/alertmanager/config:/etc/alertmanager/
    ports:
      - 9093:9093
    expose:
      - 9093

Add to the hosts file on your PC the following line:

127.0.0.1 host.docker.internal

We need it for this case:

If we want to call a url on our localhost inside a docker, we can not call it with localhost. In this case the localhost will the localhost of the docker. That is why we will call a url on our locahost with host.docker.internal alias.

Create prometheus.yml in data/prometheus/config folder:

global:
  scrape_interval:     15s 
  evaluation_interval: 15s 
rule_files:
  - "/etc/prometheus/rules.yml"
alerting:
 alertmanagers:
   - static_configs:
     - targets:
       - alertmanager:9093
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090','cadvisor:8080','node-exporter:9100']
  - job_name: 'jira'
    scheme: http 
    metrics_path: '/plugins/servlet/prometheus/metrics'
    static_configs:
      - targets: ['host.docker.internal:8080']   

Create rules.yml in data/prometheus/config folder:

groups:
  - name: AllInstances
    rules:
    - alert: InstanceDown
      expr: up == 0
      for: 1m
      annotations:
        title: 'Instance {{ $labels.instance }} down'
        description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minute.'
      labels:
        severity: 'critical'

    - alert: TooManyUsers
      expr: jira_all_active_users_gauge > 1
      annotations:
        title: 'Too many users for {{ $labels.instance }}'
        description: '{{ $labels.instance }} of job {{ $labels.job }} has more than 1 user.'
      labels:
        severity: 'meduim'

Go to your Slack and configure Incoming Webhook for the channel where you want to see alerts. As a result you will get a link which will let you add messages to the channel. In my case the link is this one: https://hooks.slack.com/services/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

Create alertmanager.yml in data/alertmanager/config folder:

global:
  resolve_timeout: 1m
  slack_api_url: 'https://hooks.slack.com/services/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'
 
route:
  receiver: 'slack-notifications'
 
receivers:
- name: 'slack-notifications'
  slack_configs:
  - channel: '#alerts'
    send_resolved: true
    icon_url: https://avatars3.githubusercontent.com/u/3380462
    title: |-
      [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }}
      {{- if gt (len .CommonLabels) (len .GroupLabels) -}}
        {{" "}}(
        {{- with .CommonLabels.Remove .GroupLabels.Names }}
          {{- range $index, $label := .SortedPairs -}}
            {{ if $index }}, {{ end }}
            {{- $label.Name }}="{{ $label.Value -}}"
          {{- end }}
        {{- end -}}
        )
      {{- end }}
    text: >-
      {{ range .Alerts -}}
      *Alert:* {{ .Annotations.title }}{{ if .Labels.severity }} - `{{ .Labels.severity }}`{{ end }}
 
      *Description:* {{ .Annotations.description }}
 
      *Details:*
        {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}`
        {{ end }}
      {{ end }}

Run with docker-compose:

docker-compose up

Test alerts

Add one more user in Jira and you will get a notification in the alerts channel in Slack. If you remove this user, you will get a message in the Slack channel that the issue has been resolved.

Stop Jira containers and you will get a notification in the alerts channel in Slack that Jira is down. If you run Jira containers again, you will get a message in the Slack channel that the issue has been resolved.

One thought on “Atlassian Jira, Prometheus and Slack integration in 15 minutes

  1. If you want to use Atlassian image. Then your docker-compose.yml should look like this:
    version: ‘3’
    services:
    jira:
    image: atlassian/jira-software
    environment:
    – JVM_SUPPORT_RECOMMENDED_ARGS=-Datlassian.plugins.enable.wait=300
    – JVM_MINIMUM_MEMORY=2G
    – JVM_MAXIMUM_MEMORY=4G
    – ATL_JDBC_URL=jdbc:postgresql://jiradb:5432/jira
    – ATL_JDBC_USER=jira
    – ATL_JDBC_PASSWORD=secret
    – ATL_DB_DRIVER=org.postgresql.Driver
    – ATL_DB_TYPE=postgres72
    volumes:
    – ./data:/var/atlassian/application-data/jira
    ports:
    – 8080:8080
    depends_on:
    – jiradb
    restart: always

    jiradb:
    image: postgres:9.6
    environment:
    – POSTGRES_PASSWORD=secret
    – POSTGRES_USER=jira
    – POSTGRES_DB=jira
    volumes:
    – ./db:/var/lib/postgresql/data
    ports:
    – 5432:5432
    restart: always

Leave a Reply

%d bloggers like this: