The Butler CMS (butler) tool is designed to grab any configuration files, defined in its configuration file, from a remote location/repository via http(s)/s3(AWS)/blob(Azure)/file/etcd and side load them onto another locally running container.
The butler configuration file is a TOML formatted file. You can store the file locally (using a mounted filesystem), or on a remote server. The proper formatting for the config file can be found here
Butler uses GitHub Actions for continuous integration and deployment.
| Workflow | Trigger | Description |
|---|---|---|
| CI | Push to main/master, PRs | Runs unit tests and builds images |
| PR Build | Pull requests | Builds preview images tagged with PR number |
| Release | Tags (v*) |
Builds and publishes to ghcr.io |
| Cleanup | PR closed | Removes PR preview images |
Images are published to GitHub Container Registry:
# Pull the latest release
docker pull ghcr.io/adobe/butler:latest
# Pull a specific version
docker pull ghcr.io/adobe/butler:v1.4.0
# Pull a PR preview (for testing)
docker pull ghcr.io/adobe/butler:pr-123To create a new release:
# Tag the release
git tag v1.4.0
git push origin v1.4.0The release workflow will automatically:
- Run unit tests
- Build multi-platform images (amd64 + arm64)
- Push to ghcr.io with version tags
- Create a GitHub Release with auto-generated notes
Here is a quick diagram that contains all the elements of what butler does, and how it is intended to interact with other systems.
To help understand more of how butler functions, here is a work flow diagram showing, in more detail, the work butler does.
There are various ways that you can run butler. We will ultimately deploy butler via DCOS, and you can run this on your local machine to do some testing.
%
./butler -h
Usage of ./butler:
-config.path string
Full remote path to butler configuration file (eg: full URL scheme://path).
-config.retrieve-interval string
The interval, in seconds, to retrieve new butler configuration files. (default "300")
-etcd.endpoints string
The endpoints to connect to etcd.
-http.auth_token string
HTTP auth token to use for HTTP authentication.
-http.auth_type string
HTTP auth type (eg: basic / digest / token-key) to use. If empty (by default) do not use HTTP authentication.
-http.auth_user string
HTTP auth user to use for HTTP authentication
-http.retries string
The number of http retries for GET requests to obtain the butler configuration files (default "5")
-http.retry_wait_max string
The maximum amount of time to wait before attemping to retry the http config get operation. (default "15")
-http.retry_wait_min string
The minimum amount of time to wait before attemping to retry the http config get operation. (default "5")
-http.timeout string
The http timeout, in seconds, for GET requests to obtain the butler configuration file. (default "10")
-log.level string
The butler log level. Log levels are: debug, info, warn, error, fatal, panic. (default "info")
-s3.region string
The S3 Region that the config file resides.
-test
Are we testing butler? (probably not!)
-tls.insecure-skip-verify
Disable SSL verification for etcd and https.
-version
Print version information.
%
Valid schemes are: blob (Azure), etcd, file, http (or https), and s3 (AWS)
Butler supports the usre of environment variables. Any field that is prefixed with env: will be looked up in the environment. This will work for all command line options, and MOST configuration file options.
There are only a few places in the configuration file where environment variables will not be used. Any value that is used which defines a new section/nest for the butler configuration will not look up any environment variables. This is due to how the configuration file is nested.
For example, the following settings will not do environment variable lookups.
- In the
config-managerssection of thebutler.tomlwhere configuration managers are defined. - As the definition for the configuration manager.
- In the
repossection in the configuration manager section. - As the definition for the configuration manager repository.
- As the
methodin the configuration manager repository. - As the definition for the configuration manager repository.
You should get the gist at this point. Refer to the butler.toml.sample configuration for additional examples.
% ./butler -config.path http://localhost/butler/config/butler.toml -config.retrieve-interval 10 -log.level info
INFO[2017-10-11T14:24:29+01:00] Starting Butler CMS version v1.2.1
^C
[master]
%
When you execute butler with the above arguments, you are asking butler to grab its configuration file from http://localhost/butler/config/butler.toml, and try to re-retrieve and refresh it every 10 seconds. It will also use the default log level of INFO. If you need more verbosity to your output, specify debug as the logging level argument.
Butler CMS supports both Basic and Digest based HTTP authentication. If your butler.toml is behind an authenticated webserver, then on the CLI you must provide the following flags:
-http.auth_type- This is the backend authentication type. Choose eitherbasic,digest, ortoken-key.-http.auth_user- This is the user to authenticate as.-http.auth_token- This is the authentication token.
With any of these flags, they can be retrieved form the environment. Refer to the "Use of Environment Variables" section for more information.
- basic - This is your standard
Authorization: basicheader. - digest - This is your sandard
Authorization: digestheader. - token-key - This is a custom
Authorization: token=foo, key=barheader. Use -http.auth_user field for token and -http.auth_token field for the key.
% ./butler -config.path etcd://etcd.mesos/butler/butler.toml -etcd.endpoints http://etcd.mesos:1026 -log.level info
INFO[2018-05-10T11:34:05Z] Starting Butler CMS version v1.2.1
INFO[2018-05-10T11:34:05Z] Config::Init(): initializing butler config.
WARN[2018-05-10T11:34:05Z] ButlerConfig::Init() Above \"NewHttpMethod(): could not convert\" warnings may be safely disregarded.
INFO[2018-05-10T11:34:05Z] Config::Init(): butler config initialized.
INFO[2018-05-10T11:34:05Z] ButlerConfig::Handler(): entering.
INFO[2018-05-10T11:34:05Z] Config::RunCMHandler(): entering
^C
%
You can grab the butler.toml directly from etcd, and you can also create a repo which utilizes etcd within the butler.toml. Refer to this example.
You can easily add the files into etcd by the following commands:
etcdctl --endpoint http://etcd.mesos:1026 mkdir /butler
etcdctl --endpoint http://etcd.mesos:1026 set /butler/butler.toml "$(cat /tmp/butler.toml)"
Note that this should support both etcd v2 and v3.
% ./butler -config.path s3://s3-bucket/config/butler.toml -config.retrieve-interval 10 -log.level info -s3.region <aws-region>
INFO[2017-10-11T14:24:29+01:00] Starting Butler CMS version v1.2.1
^C
[master]
%
When you execute butler with the above arguments, you are asking butler to grab its configuration file from S3 storage using bucket s3-bucket, file key config/butler.toml and the aws-region as specified by s3.region, and try to re-retrieve and refresh it every 10 seconds. It will also use the default log level of INFO. If you need more verbosity to your output, specify debug as the logging level argument.
In order to use the butler Azure CLI, you must set the appropriate environment variables.
BUTLER_STORAGE_TOKEN- This is the API Token to your Azure Storage Container resource
The following environment variable is optional
BUTLER_STORAGE_ACCOUNT- This is the name of the Azure Storage Account. You can either specify this in the environment, or you can specify it in the butler.toml configuration file. See the example file for reference under./contrib/butler.toml.sample.
The command line option looks like this:
% ./butler -config.path blob://azure-storage-account/azure-blob-container/butler.toml -config.retrieve-interval 10 -log.level info
{
"volumes": null,
"id": "/prometheus-server-butler2",
"cmd": null,
"args": [
"-config.path",
"http://server/butler.toml"
],
"user": null,
"env": null,
"instances": 1,
"cpus": 0.05,
"mem": 20,
"disk": 0,
"gpus": 0,
"executor": null,
"constraints": [
[
"hostname",
"LIKE",
"1.2.3.4"
],
[
"hostname",
"UNIQUE"
]
],
"fetch": null,
"storeUrls": null,
"backoffSeconds": 1,
"backoffFactor": 1.15,
"maxLaunchDelaySeconds": 3600,
"container": {
"docker": {
"image": "matthsmi/butler:x.y.z",
"forcePullImage": false,
"privileged": false,
"parameters": [
{
"key": "volume",
"value": "/opt/prometheus:/opt/prometheus:z,rw"
}
],
"portMappings": [
{
"containerPort": 8080,
"protocol": "tcp",
"servicePort": 10057
}
],
"network": "BRIDGE"
}
},
"healthChecks": [
{
"protocol": "HTTP",
"path": "/health-check",
"gracePeriodSeconds": 5,
"intervalSeconds": 20,
"timeoutSeconds": 20,
"maxConsecutiveFailures": 3,
"ignoreHttp1xx": false
}
],
"readinessChecks": null,
"dependencies": null,
"upgradeStrategy": {
"minimumHealthCapacity": 1,
"maximumOverCapacity": 1
},
"labels": null,
"acceptedResourceRoles": [
"*",
"slave_public"
],
"residency": null,
"secrets": null,
"taskKillGracePeriodSeconds": null,
"portDefinitions": [
{
"port": 10057,
"protocol": "tcp",
"labels": {
}
}
],
"requirePorts": false
}
Refer to the contrib/ directory for more information about the butler.toml configuration file, and all its features.
By default, butler requires all managed configuration files to have #butlerstart at the beginning and #butlerend at the end. This ensures butler is managing legitimate configuration files.
However, for some use cases (like Kubernetes ConfigMaps or other configurations that cannot easily include these markers), you can disable this validation per-manager by setting skip-butler-header = "true":
[mymanager]
repos = ["myrepo"]
skip-butler-header = "true"
# ... other optionsWhen skip-butler-header is enabled:
- Butler will not require
#butlerstartand#butlerendmarkers - YAML syntax validation still occurs for
.yaml/.ymlfiles - JSON syntax validation still occurs for
.jsonfiles - Text files are accepted without any validation
Butler supports a watch-only mode designed for Kubernetes ConfigMap monitoring scenarios. When enabled, butler monitors files for changes using hash comparison and triggers reloads, without writing any files to disk.
This is particularly useful when:
- Configuration files are mounted from Kubernetes ConfigMaps (read-only)
- You want butler to detect changes and trigger reloads without file I/O overhead
- The source files are already in place and just need change detection
Enable watch-only mode per-manager by setting watch-only = "true":
[jenkins]
repos = ["jcasc-local"]
# Enable watch-only mode - detect changes and reload, don't write files
watch-only = "true"
# When watch-only is true, dest-path is optional
# dest-path = "/var/tmp/butler-jcasc" # Not needed in watch-only mode
clean-files = "false"
skip-butler-header = "true"
enable-cache = "false"
primary-config-name = "jcasc-config.yaml"
[jenkins.jcasc-local]
method = "file"
repo-path = "/usr/share/jenkins/init.jcasc.d"
primary-config = ["05-config-files.yaml", "05-credentials.yaml", "10-defaults.yaml"]
[jenkins.reloader]
method = "https"
[jenkins.reloader.https]
host = "localhost"
port = "4430"
uri = "/reload-configuration-as-code/?casc-reload-token=mytoken"
method = "post"
insecure-skip-verify = "true"
retries = "3"
timeout = "30"- Butler reads and hashes the source files from
repo-path - Butler compares hashes to the previous run (stored in memory)
- If hashes differ → trigger the configured reloader
- Never writes to
dest-path
- First run: Always triggers a reload (no previous hashes to compare)
- Container restart: Triggers a reload (in-memory hashes are lost)
- No file writes: Eliminates disk I/O for read-only filesystems
dest-pathoptional: Not required whenwatch-only = "true"clean-filesignored: File cleanup is skipped in watch-only mode
- Jenkins JCasC ConfigMap monitoring: Detect ConfigMap updates and trigger Jenkins reload
- Prometheus/Alertmanager configs: Monitor externally-managed configs
- GitOps scenarios: Configs managed by Helm/ArgoCD, butler just triggers reloads
Butler uses Docker Buildx Bake for building container images. All build configuration is defined in docker-bake.hcl.
- Docker with Buildx support (Docker 19.03+)
- Make (optional, but recommended)
# Build the butler image
make build
# Build all images (butler + debug)
make build-all
# Build for multiple platforms (amd64 + arm64)
make build-multiplatform| Command | Description |
|---|---|
make build |
Build the butler production image |
make build-all |
Build butler and butler-debug images |
make build-multiplatform |
Build for linux/amd64 and linux/arm64 |
make build-local |
Build binary locally (no Docker) |
| Variable | Description | Default |
|---|---|---|
VERSION |
Version tag for the image | dev |
REGISTRY |
Docker registry hostname | (none - uses local) |
REGISTRY_PREFIX |
Path prefix within the registry | (none) |
To push images to an internal registry (e.g., Artifactory):
# Set environment variables
export REGISTRY="artifactory.example.com"
export REGISTRY_PREFIX="docker-local/"
export VERSION="v1.4.0"
# Login to your registry
docker login $REGISTRY
# Build and push in one step
make push
# Or push all images (butler + debug)
make push-allThe images will be tagged as:
artifactory.example.com/docker-local/butler:v1.4.0artifactory.example.com/docker-local/butler:latest
You can also use docker buildx bake directly:
# Show what would be built
docker buildx bake --print
# Build specific target
docker buildx bake butler
# Build and push
docker buildx bake butler --push
# Build with custom variables
VERSION=v1.4.0 REGISTRY=myregistry.com docker buildx bake butlerButler uses GitHub Actions to automatically create releases when PRs are merged to the main branch.
Every PR must have one of the following labels to indicate the type of version bump:
| Label | Version Bump | Example |
|---|---|---|
release:major |
Major version | v1.0.0 → v2.0.0 |
release:minor |
Minor version | v1.0.0 → v1.1.0 |
release:patch |
Patch version | v1.0.0 → v1.0.1 |
release:skip |
No release | Skips automatic release |
When to use each label:
release:major: Breaking changes, incompatible API changesrelease:minor: New features, backwards-compatible additionsrelease:patch: Bug fixes, documentation updates, minor changesrelease:skip: CI/CD changes, README updates that don't need a release
When a PR is merged to main or master (without release:skip label), the auto-release workflow will:
- Read the release label to determine version bump type
- Update the
VERSIONfile and create a git tag - Build and push container images to ghcr.io
- Create a GitHub Release with auto-generated notes
The required labels are automatically created when you first push to main. You can also manually trigger the setup:
# Via GitHub CLI
gh workflow run setup-labels.yml
# Or go to Actions → Setup Labels → Run workflowTo create a release manually, push a version tag:
git tag v1.3.0
git push origin v1.3.0
## Testing
Butler has unit testing and acceptance testing, both run inside Docker containers for consistency.
### Running Tests
```bash
# Run all tests (unit + acceptance)
make test
# Run unit tests only
make test-unit
# Run acceptance tests only
make test-accept
# Run tests locally (no Docker)
make test-local| Command | Description |
|---|---|
make test |
Run all tests (unit + acceptance) |
make test-unit |
Run unit tests in container, outputs coverage to out/coverage/ |
make test-accept |
Run acceptance tests in container |
make test-local |
Run tests locally without Docker |
make enter-test-unit |
Interactive shell in unit test container |
make enter-test-accept |
Interactive shell in acceptance test container |
Unit tests use the check.v1 testing package (gopkg.in/check.v1). Coverage reports are generated and saved to out/coverage/.
make test-unit
# Coverage reports available in out/coverage/The acceptance testing tests how butler operates overall. Butler is run with the -test flag which performs a full config operation once. If there are failures (unable to parse configuration, missing variables, etc.), it exits with status code 1.
Out of the box, it tests http://, https://, and file:// endpoints.
To test against Azure Blob storage, set the following environment variables:
| Variable | Description |
|---|---|
BUTLER_BLOB_TEST_CONFIGS |
Space-delimited list of blob:// URLs to test |
BUTLER_BLOB_TEST_RESPONSES |
Space-delimited list of expected return codes |
Example:
export BUTLER_BLOB_TEST_CONFIGS="blob://account/container/butler1.toml blob://account/container/butler2.toml"
export BUTLER_BLOB_TEST_RESPONSES="0 0 1"The test script is located at ./files/tests/scripts/azure.sh
To test against AWS S3 storage, set the following environment variables:
| Variable | Description |
|---|---|
BUTLER_S3_TEST_CONFIGS |
Space-delimited list of s3:// URLs to test |
BUTLER_S3_TEST_RESPONSES |
Space-delimited list of expected return codes |
Example:
export BUTLER_S3_TEST_CONFIGS="s3://bucket/butler1.toml s3://bucket/butler2.toml"
export BUTLER_S3_TEST_RESPONSES="0 1 1"The test script is located at ./files/tests/scripts/s3.sh
# Format Go code
make fmt
# Run linter
make lint
# Run go vet
make vet
# Run all checks (fmt, vet, lint)
make check# Build binary locally
make build-local
# Run butler locally
make run
# Start local etcd for testing
make start-etcd
# Start local Prometheus for testing
make start-prometheusRun make help for a full list of available targets:
Build targets:
make build Build butler image using docker buildx bake
make build-all Build all images (butler + debug)
make build-local Build local binary (no Docker)
make build-multiplatform Build for amd64 and arm64
Test targets:
make test Run all tests (unit + acceptance)
make test-unit Run unit tests in container
make test-accept Run acceptance tests in container
make test-local Run tests locally (no Docker)
make enter-test-unit Interactive unit test container
make enter-test-accept Interactive acceptance test container
Code quality:
make fmt Format Go code
make lint Run linter
make vet Run go vet
make check Run fmt, vet, and lint
Utility:
make clean Remove build artifacts
make bake-print Show docker buildx bake plan
butler provides DCOS health checks by exposing an http service with a /health-check endpoint. It exposes various configuration, and realtime information in JSON format regarding the butler process.
% http get localhost:8080/health-check
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 12 Oct 2017 10:44:50 GMT
Transfer-Encoding: chunked
{
"config-path": "http://localhost/butler/config/butler.toml",
"config-settings": {
"globals": {
"exit-on-failure": false,
"scheduler-interval": 10
},
"managers": {
"alertmanager": {
"cache-path": "/opt/cache/alertmanager",
"clean-files": true,
"dest-path": "/opt/alertmanager",
"enable-cache": true,
"last-run": "2017-10-12T11:44:50.29930327+01:00",
"mustache-subs": {
"endpoint": "external",
"ethos-cluster-id": "ethos01-dev-or1"
},
"name": "alertmanager",
"opts": {
"alertmanager.repo3.domain.com": {
"additional-config": null,
"method": "http",
"opts": {
"retries": 5,
"retry-wait-max": 10,
"retry-wait-min": 5,
"timeout": 10
},
"primary-config": [
"alertmanager.yml"
],
"repo": "repo3.domain.com",
"uri-path": "/butler/configs/alertmanager"
},
"alertmanager.repo4.domain.com": {
"additional-config": null,
"method": "http",
"opts": {
"retries": 5,
"retry-wait-max": 10,
"retry-wait-min": 5,
"timeout": 10
},
"primary-config": [
"alertmanager-2.yml"
],
"repo": "repo4.domain.com",
"uri-path": "/butler/configs/alertmanager"
}
},
"primary-config-name": "alertmanager.yml",
"reloader": {
"method": "http",
"opts": {
"content-type": "application/json",
"host": "localhost",
"method": "post",
"payload": "{}",
"port": 9093,
"retries": 5,
"retry-wait-max": 10,
"retry-wait-min": 5,
"timeout": 10,
"uri": "/-/reload"
}
},
"urls": [
"repo3.domain.com",
"repo4.domain.com"
]
},
"prometheus": {
"cache-path": "/opt/cache/prometheus",
"clean-files": true,
"dest-path": "/opt/prometheus",
"enable-cache": true,
"last-run": "2017-10-12T11:44:50.29659399+01:00",
"mustache-subs": {
"endpoint": "external",
"ethos-cluster-id": "ethos01-dev-or1"
},
"name": "prometheus",
"opts": {
"prometheus.repo1.domain.com": {
"additional-config": [
"alerts/commonalerts.yml",
"butler/butler.yml"
],
"method": "http",
"opts": {
"retries": 5,
"retry-wait-max": 10,
"retry-wait-min": 5,
"timeout": 10
},
"primary-config": [
"prometheus.yml",
"prometheus-other.yml"
],
"repo": "repo1.domain.com",
"uri-path": "/butler/configs/prometheus"
},
"prometheus.repo2.domain.com": {
"additional-config": [
"alerts/tenant.yml",
"butler/butler-repo2.yml"
],
"method": "http",
"opts": {
"retries": 5,
"retry-wait-max": 10,
"retry-wait-min": 5,
"timeout": 10
},
"primary-config": [
"prometheus-repo2.yml",
"prometheus-repo2-other.yml"
],
"repo": "repo2.domain.com",
"uri-path": "/butler/configs/prometheus"
}
},
"primary-config-name": "prometheus.yml",
"reloader": {
"method": "http",
"opts": {
"content-type": "application/json",
"host": "localhost",
"method": "post",
"payload": "{}",
"port": 9090,
"retries": 5,
"retry-wait-max": 10,
"retry-wait-min": 5,
"timeout": 10,
"uri": "/-/reload"
}
},
"urls": [
"repo1.domain.com",
"repo2.domain.com"
]
}
}
},
"log-level": 5,
"retrieve-interval": 10,
"version": "v1.0.0"
}
[master]
%
butler provides native Prometheus of the butler go binary by exposing an http service with a /metrics endpoint. This includes both butler specific metric information (prefixed with butler_), and internal go and process related metrics (prefixed with go_ and process_)
% http get localhost:8080/metrics
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 1381
Content-Type: text/plain; version=0.0.4
Date: Wed, 26 Jul 2017 12:04:57 GMT
# HELP butler_localconfig_reload_success Did butler successfully reload prometheus
# TYPE butler_localconfig_reload_success gauge
butler_localconfig_reload_success 1
# HELP butler_localconfig_reload_time Time that butler successfully reload prometheus
# TYPE butler_localconfig_reload_time gauge
butler_localconfig_reload_time 1.501070697e+09
# HELP butler_localconfig_render_success Did butler successfully render the prometheus.yml
# TYPE butler_localconfig_render_success gauge
butler_localconfig_render_success 1
# HELP butler_localconfig_render_time Time that butler successfully rendered the prometheus.yml
# TYPE butler_localconfig_render_time gauge
butler_localconfig_render_time 1.501070527e+09
# HELP butler_remoterepo_config_valid Is the butler configuration valid
# TYPE butler_remoterepo_config_valid gauge
butler_remoterepo_config_valid{config_file="commonalerts.yml"} 1
butler_remoterepo_config_valid{config_file="prometheus.yml"} 1
butler_remoterepo_config_valid{config_file="tenant.yml"} 1
# HELP butler_remoterepo_contact_success Did butler successfully contact the remote repository
# TYPE butler_remoterepo_contact_success gauge
butler_remoterepo_contact_success{config_file="commonalerts.yml"} 1
butler_remoterepo_contact_success{config_file="prometheus.yml"} 1
butler_remoterepo_contact_success{config_file="tenant.yml"} 1
# HELP butler_remoterepo_contact_time Time that butler successfully contacted the remote repository
# TYPE butler_remoterepo_contact_time gauge
butler_remoterepo_contact_time{config_file="commonalerts.yml"} 1.501070685e+09
butler_remoterepo_contact_time{config_file="prometheus.yml"} 1.501070697e+09
butler_remoterepo_contact_time{config_file="tenant.yml"} 1.501070685e+09
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0.000236024
go_gc_duration_seconds{quantile="0.25"} 0.000236024
go_gc_duration_seconds{quantile="0.5"} 0.000236024
go_gc_duration_seconds{quantile="0.75"} 0.000236024
go_gc_duration_seconds{quantile="1"} 0.000236024
go_gc_duration_seconds_sum 0.000236024
go_gc_duration_seconds_count 1
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 18
# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
# TYPE go_memstats_alloc_bytes gauge
go_memstats_alloc_bytes 3.3794e+06
# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.
# TYPE go_memstats_alloc_bytes_total counter
go_memstats_alloc_bytes_total 6.070552e+06
# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.
# TYPE go_memstats_buck_hash_sys_bytes gauge
go_memstats_buck_hash_sys_bytes 1.445366e+06
# HELP go_memstats_frees_total Total number of frees.
# TYPE go_memstats_frees_total counter
go_memstats_frees_total 15629
# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.
# TYPE go_memstats_gc_sys_bytes gauge
go_memstats_gc_sys_bytes 333824
# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use.
# TYPE go_memstats_heap_alloc_bytes gauge
go_memstats_heap_alloc_bytes 3.3794e+06
# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used.
# TYPE go_memstats_heap_idle_bytes gauge
go_memstats_heap_idle_bytes 106496
# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.
# TYPE go_memstats_heap_inuse_bytes gauge
go_memstats_heap_inuse_bytes 4.251648e+06
# HELP go_memstats_heap_objects Number of allocated objects.
# TYPE go_memstats_heap_objects gauge
go_memstats_heap_objects 17404
# HELP go_memstats_heap_released_bytes Number of heap bytes released to OS.
# TYPE go_memstats_heap_released_bytes gauge
go_memstats_heap_released_bytes 0
# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system.
# TYPE go_memstats_heap_sys_bytes gauge
go_memstats_heap_sys_bytes 4.358144e+06
# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection.
# TYPE go_memstats_last_gc_time_seconds gauge
go_memstats_last_gc_time_seconds 1.5010706071801429e+09
# HELP go_memstats_lookups_total Total number of pointer lookups.
# TYPE go_memstats_lookups_total counter
go_memstats_lookups_total 466
# HELP go_memstats_mallocs_total Total number of mallocs.
# TYPE go_memstats_mallocs_total counter
go_memstats_mallocs_total 33033
# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures.
# TYPE go_memstats_mcache_inuse_bytes gauge
go_memstats_mcache_inuse_bytes 9600
# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system.
# TYPE go_memstats_mcache_sys_bytes gauge
go_memstats_mcache_sys_bytes 16384
# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures.
# TYPE go_memstats_mspan_inuse_bytes gauge
go_memstats_mspan_inuse_bytes 45144
# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system.
# TYPE go_memstats_mspan_sys_bytes gauge
go_memstats_mspan_sys_bytes 49152
# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place.
# TYPE go_memstats_next_gc_bytes gauge
go_memstats_next_gc_bytes 4.194304e+06
# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations.
# TYPE go_memstats_other_sys_bytes gauge
go_memstats_other_sys_bytes 1.012482e+06
# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator.
# TYPE go_memstats_stack_inuse_bytes gauge
go_memstats_stack_inuse_bytes 884736
# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator.
# TYPE go_memstats_stack_sys_bytes gauge
go_memstats_stack_sys_bytes 884736
# HELP go_memstats_sys_bytes Number of bytes obtained from system.
# TYPE go_memstats_sys_bytes gauge
go_memstats_sys_bytes 8.100088e+06
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 0.12
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1024
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 31
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 1.0821632e+07
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.50107052601e+09
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 2.39341568e+08
[master]
%
Contributions are welcomed! Read the Contributing Guide for more information.
This project is licensed under the Apache V2 License. See LICENSE for more information.


