Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,42 @@ $ curl -sS 'http://localhost:5000/harbor/https://docker.eyeseetea.com/api/v2.0/q
## Glowroot

Glowroot is an open-source Java APM (Application Performance Monitoring) tool. It can help detect and diagnose application performance problems, tracing slow requests, errors, response time breakdowns, SQL capture and more.
When starting a container, there are two options to enable glowroot on the Tomcat process:
- Use option `--glowroot` to use the latest version of glowroot in the Tomcat process. This requires internet access to be able to retrieve the file.
- Use option `--glowroot-zip=FILE` to specify the zip file with the version of glowroot to run in the Tomcat process. This takes precedence over the other option.
When enabling glowroot, it will start listening on port 4000/tcp so you can connect via browser to its interface. You may override this port with:
- `--glowroot-port=PORT` to specify the APM glowroot port.
The startup script in the core container expects a `/opt/glowroot.zip` file; if it exists, it will decompress that file and enable a default configuration for glowroot in the tomcat process.
The only needed parameter to use glowroot is the `--glowroot-port`, as the metrics are exposes through its own http connection, so the port must be opened in the container.
To use glowroot:

### Run d2-docker with glowroot enabled in the default port at the latest version available
- start d2-docker with `--glowroot-port=<PORT>` (default port for glowroot is 4000, but any available port can be used)
- download the latest version of glowroot to the host machine:

```
$ d2-docker start docker.eyeseetea.com/eyeseetea/dhis2-data:2.37.9-sierra --glowroot
lastversion=$(wget -q -O - https://api.github.com/repos/glowroot/glowroot/releases/latest | jq '.tag_name' | sed 's_"__g')
wget -q https://github.com/glowroot/glowroot/releases/download/$lastversion/glowroot-${lastversion#v}-dist.zip
```

- determine the core instance name (note that as there might be several d2-docker instances running, you must pick the one you want manually from the list)

```
docker ps | awk '/core.1/ {print $NF}'
```

- copy the zip file to the core container with the filename `/opt/glowroot.zip`:

```
docker cp glowroot-0.14.4-dist.zip ${core_instance_name}:/opt/glowroot.zip
```

- restart the core container:

```
docker restart ${core_instance_name}
```

Glowroot is configured to store its data for several days, so the size of its folder should be limited to some extent. This size may be further reduced editing the configuration via WebUI, but might require a restart of the container. Configuration (and glowroot historical data) will be kept unless the `/opt/glowroot` folder is deleted from the container and restarted.

To remove glowroot from a container you must:

- connect to the core container (`docker exec -it ${core_instance_name} bash`)
- inside the core container, remove the `/opt/glowroot.zip` file
- inside the core container, remove the `/opt/glowroot` folder
- inside the core container, remove the `/usr/local/tomcat/bin/setenv.sh` file. (This is not extrictly necessary as the jar file will no longer exist and won't be able to start, but if it is not removed, some warnings/errors may be generated upon tomcat start)
- exit the core container and restart it (`docker restart ${core_instance_name}`)
6 changes: 1 addition & 5 deletions src/d2_docker/commands/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ def setup(parser):
parser.add_argument("--enable-postgres-queries-logging", action="store_true",
help="Enable Postgres queries logging")

parser.add_argument("--glowroot", action="store_true", help="Enables glowroot in tomcat in latest version")
parser.add_argument("--glowroot-zip", metavar="FILE", help="ZIP file with glowroot binaries")
parser.add_argument("--glowroot-port", metavar="PORT", help="Set glowroot port")


Expand Down Expand Up @@ -117,9 +115,7 @@ def start(args):
java_opts=args.java_opts,
postgis_version=args.postgis_version,
enable_postgres_queries_logging=args.enable_postgres_queries_logging,
glowroot=args.glowroot,
glowroot_zip=args.glowroot_zip,
glowroot_port=args.glowroot_port,
glowroot_port=args.glowroot_port
)

if args.detach:
Expand Down
27 changes: 27 additions & 0 deletions src/d2_docker/config/dhis2-core-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,33 @@ setup_glowroot() {
fi
if [ -d $GLOWROOT_DIR ] ; then
echo '{ "web": { "bindAddress": "0.0.0.0", "port": "4000" }}' > $GLOWROOT_DIR/admin.json
echo '{"transactions":{"slowThresholdMillis":2000,"profilingIntervalMillis":1000,"captureThreadStats":true},
"jvm":{"maskSystemProperties":["*password*","*token*","*access*","*secret*"],"maskMBeanAttributes":["*password*","*token*","*access*","*secret*"]},
"uiDefaults":{"defaultTransactionType":"Web","defaultPercentiles":[50,95,99],"defaultGaugeNames":["java.lang:type=Memory:HeapMemoryUsage.used"]},
"advanced":{"immediatePartialStoreThresholdSeconds":60,"maxTransactionAggregates":500,"maxQueryAggregates":500,"maxServiceCallAggregates":500,
"maxTraceEntriesPerTransaction":2000,"maxProfileSamplesPerTransaction":50000,"mbeanGaugeNotFoundDelaySeconds":60},"gauges":[{"mbeanObjectName":"java.lang:type=Memory",
"mbeanAttributes":[{"name":"HeapMemoryUsage.used"}]},{"mbeanObjectName":"java.lang:type=GarbageCollector,name=*","mbeanAttributes":[{"name":"CollectionCount","counter":true},
{"name":"CollectionTime","counter":true}]},{"mbeanObjectName":"java.lang:type=MemoryPool,name=*","mbeanAttributes":[{"name":"Usage.used"}]},
{"mbeanObjectName":"java.lang:type=OperatingSystem","mbeanAttributes":[{"name":"FreePhysicalMemorySize"},{"name":"ProcessCpuLoad"},{"name":"SystemCpuLoad"}]}],
"plugins":[{"properties":{"stackTraceThresholdMillis":1000},"id":"cassandra"},{"properties":{"stackTraceThresholdMillis":1000},"id":"elasticsearch"},
{"properties":{"sessionUserAttribute":"","captureSessionAttributes":[],"captureRequestParameters":["*"],"maskRequestParameters":["*password*","*token*","*access*","*secret*"],
"captureRequestHeaders":[],"captureResponseHeaders":[],"traceErrorOn4xxResponseCode":false,"captureRequestRemoteAddr":false,"captureRequestRemoteHostname":false,
"captureRequestRemotePort":false,"captureRequestLocalAddr":false,"captureRequestLocalHostname":false,"captureRequestLocalPort":false,"captureRequestServerHostname":false,
"captureRequestServerPort":false},"id":"jakartaservlet"},{"properties":{"captureRequestHeaders":[],"maskRequestHeaders":["Authorization"],"captureRequestRemoteAddr":false,
"captureRequestRemoteHost":false,"captureResponseHeaders":[],"traceErrorOn4xxResponseCode":false},"id":"java-http-server"},{"properties":{"useAltTransactionNaming":false},
"id":"jaxrs"},{"properties":{"captureBindParametersIncludes":[".*"],"captureBindParametersExcludes":[],"captureResultSetNavigate":true,"captureResultSetGet":false,
"captureConnectionPoolLeaks":false,"captureConnectionPoolLeakDetails":false,"captureGetConnection":true,"captureConnectionClose":false,"capturePreparedStatementCreation":false,
"captureStatementClose":false,"captureTransactionLifecycleTraceEntries":false,"captureConnectionLifecycleTraceEntries":false,"stackTraceThresholdMillis":1000},"id":"jdbc"},
{"properties":{"traceErrorOnErrorWithThrowable":true,"traceErrorOnErrorWithoutThrowable":false,"traceErrorOnWarningWithThrowable":false,"traceErrorOnWarningWithoutThrowable":false},
"id":"logger"},{"properties":{"stackTraceThresholdMillis":1000},"id":"mongodb"},{"properties":{"useAltTransactionNaming":false},"id":"play"},{"properties":{"sessionUserAttribute":"",
"captureSessionAttributes":[],"captureRequestParameters":["*"],"maskRequestParameters":["*password*","*token*","*access*","*secret*"],"captureRequestHeaders":[],
"captureResponseHeaders":[],"traceErrorOn4xxResponseCode":false,"captureRequestRemoteAddr":false,"captureRequestRemoteHostname":false,"captureRequestRemotePort":false,
"captureRequestLocalAddr":false,"captureRequestLocalHostname":false,"captureRequestLocalPort":false,"captureRequestServerHostname":false,"captureRequestServerPort":false},
"id":"servlet"},{"properties":{"useAltTransactionNaming":false},"id":"spring"}],"instrumentation":[{"className":"org.hisp.dhis.webapi.controller.event.TrackedEntityInstanceController",
"methodName":"getTrackedEntityInstances","methodParameterTypes":[".."],"order":0,"captureKind":"other","transactionType":"Web","transactionNameTemplate":"/api/trackedEntityInstances: GET"},
{"className":"org.hisp.dhis.tracker.report.DefaultTrackerImportService","methodName":"importTracker","methodParameterTypes":[".."],"order":0,"captureKind":"transaction",
"transactionType":"Web","transactionNameTemplate":"/api/tracker: import","alreadyInTransactionBehavior":"capture-new-transaction","traceEntryMessageTemplate":"{{0}}",
"traceEntryStackThresholdMillis":300,"traceEntryCaptureSelfNested":true,"timerName":"Timer"}]}' > $GLOWROOT_DIR/config.json
chown -R tomcat:tomcat $GLOWROOT_DIR
chmod -R u=rwX,g=rX,o-rwx $GLOWROOT_DIR
echo 'export CATALINA_OPTS="$CATALINA_OPTS -javaagent:/opt/glowroot/glowroot.jar"' > /usr/local/tomcat/bin/setenv.sh
Expand Down
1 change: 0 additions & 1 deletion src/d2_docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ services:
- "com.eyeseetea.image-name=${DHIS2_DATA_IMAGE}"
volumes:
- home:/DHIS2_home
- ${GLOWROOT_ZIP}:/opt/glowroot.zip
- ${DHIS_CONF}:/config/override/dhis2/dhis.conf
- ${ROOT_PATH}/config:/config
- data:/data
Expand Down
4 changes: 2 additions & 2 deletions src/d2_docker/glowroot.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ def get_glowroot_zip(command, glowroot_zip, glowroot):

return utils.get_absfile_for_docker_volume(glowroot_path)

def get_port_glowroot(glowroot_port, glowroot_zip, glowroot):
def get_port_glowroot(glowroot_port):
port = glowroot_port if glowroot_port else GLOWROOT_DEFAULT_PORT
return "{}:{}".format(port, GLOWROOT_DEFAULT_PORT) if (glowroot_port or glowroot_zip or glowroot) else None
return "{}:{}".format(port, GLOWROOT_DEFAULT_PORT) if glowroot_port else None
7 changes: 2 additions & 5 deletions src/d2_docker/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from typing import Optional

import d2_docker
from d2_docker.glowroot import get_glowroot_zip, get_port_glowroot
from d2_docker.glowroot import get_port_glowroot
from .image_name import ImageName

PROJECT_NAME_PREFIX = "d2-docker"
Expand Down Expand Up @@ -262,8 +262,6 @@ def run_docker_compose(
tomcat_server=None,
postgis_version=None,
enable_postgres_queries_logging=False,
glowroot=None,
glowroot_zip=None,
glowroot_port=None,
**kwargs,
):
Expand Down Expand Up @@ -301,8 +299,7 @@ def run_docker_compose(
# Add ROOT_PATH from environment (required when run inside a docker)
("ROOT_PATH", ROOT_PATH),
("PSQL_ENABLE_QUERY_LOGS", "") if not enable_postgres_queries_logging else None,
("GLOWROOT_PORT", get_port_glowroot(glowroot_port, glowroot_zip, glowroot)),
("GLOWROOT_ZIP", get_glowroot_zip(args, glowroot_zip, glowroot)),
("GLOWROOT_PORT", get_port_glowroot(glowroot_port))
]
env = dict((k, v) for (k, v) in [pair for pair in env_pairs if pair] if v is not None)

Expand Down
Loading