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