A common problem in most java applications is monitoring the performance of your application. This has to be done before delivering your solution to your customer. There are several commercial solutions like Relic. I will propose you below an open source solution that can be self hosted and give you more or less same metrics. I will use Glowroot and will deploy it centrally in order to can monitor several java applications.

Glowroot Features

  • Trace capture for slow requests and errors
  • Continuous profiling (with very handy filtering)
  • Response time breakdown charts
  • Response time percentile charts
  • SQL capture and aggregation
  • Service call capture and aggregation
  • Configurable alerting
  • Historical rollup of all data (1m, 5m, 30m, 4h) with configurable retention

Installation

Standolone

  • Download and unzip glowroot-0.13.6-dist.zip
  • add -javaagent:path/to/glowroot.jar to your application’s JVM args
  • point your browser to http://localhost:4000

Central Collector

I will demonstrate how to install a central collector using docker technology. Four main container are needed:

  • Portainer – for container management
  • Traefik – as proxy for accessing your services with domain names
  • Cassandra DB – used by glowroot central
  • Glowroot central

It is needed to have in the same path with docker-compose file the following:

  • folder with certificates (you can omit them and comment out some lines in this file)
  • glowroot-central.properties (sample file below)
cassandra.contactPoints=cassandra
# default is to connect without credentials
cassandra.username=
# default is to connect without credentials
cassandra.password=
# default is cassandra.keyspace=glowroot
cassandra.keyspace=glowroot
# default is cassandra.consistencyLevel=QUORUM
cassandra.consistencyLevel=QUORUM
default is grpc.bindAddress=${YOUR_IP_ADDRESS}
# default is grpc.httpPort=8181
# set this to "none" in order to not serve gRPC over HTTP
grpc.httpPort=8181
grpc.httpsPort=none

Below is a sample docker-compose.yml file. You can alter it a bit for ${DOMAIN} and ${PASSWORD} variable. You have also to have in the same level with docker-compose file:

version: "3.3"

services:
  traefik:
    container_name: traefik
    image: traefik:v1.7.18-alpine
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik/traefik.toml:/etc/traefik/traefik.toml
      - ./traefik/certificates:/tls
      - traefik-data:/etc/traefik/acme
    labels:
      - traefik.backend=traefik
      - traefik.frontend.rule=Host:traefik-${DOMAIN}
      - traefik.port=8080
      - traefik.frontend.headers.SSLRedirect=true
      - traefik.frontend.entryPoints=http,https
      - traefik.docker.networks=monitoring
    restart: always
    networks:
      - monitoring

  portainer:
    container_name: portainer
    image: portainer/portainer:latest
    ports:
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer-data:/data
    labels:
      - traefik.backend=portainer
      - traefik.frontend.rule=Host:portainer-${DOMAIN}
      - traefik.port=9000
      - traefik.frontend.headers.SSLRedirect=true
      - traefik.frontend.entryPoints=http,https
      - traefik.docker.networks=monitoring
    depends_on:
      - traefik
    restart: always
    networks:
      - monitoring

  cassandra:
    container_name: cassandra
    image: cassandra:latest
    volumes:
      - cassandra-data:/var/lib/cassandra
    restart: always
    networks:
      - monitoring

  glowroot:
    container_name: glowroot
    image: glowroot/glowroot-central:0.13.4
    ports:
      - "8181:8181"
    expose:
      - "4000"
      - "8181"
    depends_on:
      - cassandra
    restart: always
    labels:
      - traefik.backend=glowroot
      - traefik.frontend.rule=Host:glowroot-${DOMAIN}
      - traefik.port=4000
      - traefik.frontend.headers.SSLRedirect=true
      - traefik.frontend.entryPoints=http,https
      - traefik.docker.networks=monitoring
    command: ["bash", "-c", "java -jar glowroot-central.jar setup-admin-user 'admin' '${PASSWORD}' && java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -jar glowroot-central.jar"]
    volumes:
      - ./glowroot/central/glowroot-central.properties:/glowroot-central/glowroot-central.properties
    networks:
      - monitoring

volumes:
  cassandra-data:
  traefik-data:
  portainer-data:

networks:
  monitoring:
    external:
      name: monitoring

Agent installation

Additionally you have to configure your java app to connect to this cental collector.

-javaagent:${PATH}/glowroot.jar -Dglowroot.agent.id=${APP}
  • ${PATH}: the path where the glowroot.jar exists
  • ${APP}: is the unique name will appear in glowroot page

Additionaly you have to put a file glowroot.properties in the same path with glowroot.jar with the following content

collector.address=http://${CENTRAL_COLLECTOR_IP}:8181
multi.dir=true

${CENTRAL_COLLECTOR_IP} is the ip where you have installed the central collector with docker-compose

Demonstration

If you have succesfully installed everything and point to the domain configured in the docker-compose file you will see a screen like this

By admin