Skip to content

adobe/butler

Butler CMS

Go Report Card Build Status codecov Butler Logo

Butler CMS (Configuration Management System) Overview

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

CI/CD

Butler uses GitHub Actions for continuous integration and deployment.

Workflows

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

Container 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-123

Creating a Release

To create a new release:

# Tag the release
git tag v1.4.0
git push origin v1.4.0

The release workflow will automatically:

  1. Run unit tests
  2. Build multi-platform images (amd64 + arm64)
  3. Push to ghcr.io with version tags
  4. Create a GitHub Release with auto-generated notes

Butler at 30,000 feet

Here is a quick diagram that contains all the elements of what butler does, and how it is intended to interact with other systems.

Butler Elements

Butler Workflow

To help understand more of how butler functions, here is a work flow diagram showing, in more detail, the work butler does.

Butler Workflow

Usage

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.

Command Line Usage

%
./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)

Use of Environment Variables

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.

  1. In the config-managers section of the butler.toml where configuration managers are defined.
  2. As the definition for the configuration manager.
  3. In the repos section in the configuration manager section.
  4. As the definition for the configuration manager repository.
  5. As the method in the configuration manager repository.
  6. 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.

Example Command Line Usage

HTTP/HTTPS CLI

% ./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.

HTTP/HTTPS CLI Authentication

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:

  1. -http.auth_type - This is the backend authentication type. Choose either basic, digest, or token-key.
  2. -http.auth_user - This is the user to authenticate as.
  3. -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.

Authentication Types
  1. basic - This is your standard Authorization: basic header.
  2. digest - This is your sandard Authorization: digest header.
  3. token-key - This is a custom Authorization: token=foo, key=bar header. Use -http.auth_user field for token and -http.auth_token field for the key.

etcd CLI

% ./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.

S3 CLI

% ./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.

Azure CLI and Usage

In order to use the butler Azure CLI, you must set the appropriate environment variables.

  1. BUTLER_STORAGE_TOKEN - This is the API Token to your Azure Storage Container resource

The following environment variable is optional

  1. 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

DCOS Deployment JSON

{
  "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
}

Butler Configuration File

Refer to the contrib/ directory for more information about the butler.toml configuration file, and all its features.

Skipping Butler Header/Footer Validation

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 options

When skip-butler-header is enabled:

  • Butler will not require #butlerstart and #butlerend markers
  • YAML syntax validation still occurs for .yaml/.yml files
  • JSON syntax validation still occurs for .json files
  • Text files are accepted without any validation

Watch-Only Mode for ConfigMap Monitoring

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

Configuration

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"

How It Works

  1. Butler reads and hashes the source files from repo-path
  2. Butler compares hashes to the previous run (stored in memory)
  3. If hashes differ → trigger the configured reloader
  4. Never writes to dest-path

Key Behaviors

  • 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-path optional: Not required when watch-only = "true"
  • clean-files ignored: File cleanup is skipped in watch-only mode

Use Cases

  • 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

Building

Butler uses Docker Buildx Bake for building container images. All build configuration is defined in docker-bake.hcl.

Prerequisites

  • Docker with Buildx support (Docker 19.03+)
  • Make (optional, but recommended)

Quick Start

# Build the butler image
make build

# Build all images (butler + debug)
make build-all

# Build for multiple platforms (amd64 + arm64)
make build-multiplatform

Build Targets

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)

Environment Variables

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)

Pushing to a Registry

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-all

The images will be tagged as:

  • artifactory.example.com/docker-local/butler:v1.4.0
  • artifactory.example.com/docker-local/butler:latest

Using Docker Buildx Bake Directly

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 butler

Releases

Butler uses GitHub Actions to automatically create releases when PRs are merged to the main branch.

Release Labels

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 changes
  • release:minor: New features, backwards-compatible additions
  • release:patch: Bug fixes, documentation updates, minor changes
  • release:skip: CI/CD changes, README updates that don't need a release

Automatic Releases

When a PR is merged to main or master (without release:skip label), the auto-release workflow will:

  1. Read the release label to determine version bump type
  2. Update the VERSION file and create a git tag
  3. Build and push container images to ghcr.io
  4. Create a GitHub Release with auto-generated notes

Setting Up Labels

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 workflow

Manual Releases

To 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

Test Targets

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

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/

Acceptance Tests

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.

Blob (Azure) Testing

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

S3 (AWS) Testing

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

Development

Code Quality

# Format Go code
make fmt

# Run linter
make lint

# Run go vet
make vet

# Run all checks (fmt, vet, lint)
make check

Local Development

# 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-prometheus

Make Targets Reference

Run 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

Health Checks

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]
%

Prometheus Metrics

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]
%

Contributing

Contributions are welcomed! Read the Contributing Guide for more information.

Licensing

This project is licensed under the Apache V2 License. See LICENSE for more information.

About

Butler CMS (Configuration Management System)

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors