Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:deneb_alpha:branches:server:monitoring
golang-github-lusitaniae-apache_exporter
apache_exporter-1.0.8.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File apache_exporter-1.0.8.obscpio of Package golang-github-lusitaniae-apache_exporter
07070100000000000041ED000000000000000000000002667C2A2400000000000000000000000000000000000000000000002000000000apache_exporter-1.0.8/.circleci07070100000001000081A4000000000000000000000001667C2A2400000237000000000000000000000000000000000000002B00000000apache_exporter-1.0.8/.circleci/config.yml--- # Prometheus has switched to GitHub action. # Circle CI is not disabled repository-wise so that previous pull requests # continue working. # This file does not generate any CircleCI workflow. version: 2.1 executors: golang: docker: - image: busybox jobs: noopjob: executor: golang steps: - run: command: "true" workflows: version: 2 prometheus: jobs: - noopjob triggers: - schedule: cron: "0 0 30 2 *" filters: branches: only: - main 07070100000002000041ED000000000000000000000003667C2A2400000000000000000000000000000000000000000000001E00000000apache_exporter-1.0.8/.github07070100000003000081A4000000000000000000000001667C2A24000000CF000000000000000000000000000000000000002D00000000apache_exporter-1.0.8/.github/dependabot.ymlversion: 2 updates: - package-ecosystem: "gomod" directory: "/" schedule: interval: "weekly" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" 07070100000004000041ED000000000000000000000002667C2A2400000000000000000000000000000000000000000000002800000000apache_exporter-1.0.8/.github/workflows07070100000005000081A4000000000000000000000001667C2A2400000A36000000000000000000000000000000000000002F00000000apache_exporter-1.0.8/.github/workflows/ci.yml--- name: CI on: pull_request: push: jobs: test: name: Test runs-on: ubuntu-latest # Whenever the Go version is updated here, .promu.yml # should also be updated. container: image: quay.io/prometheus/golang-builder:1.22-base steps: - uses: actions/checkout@v4 - uses: prometheus/promci@v0.1.0 - uses: ./.github/promci/actions/setup_environment - run: make build: name: Build runs-on: ubuntu-latest strategy: matrix: thread: [ 0, 1, 2 ] steps: - uses: actions/checkout@v4 - uses: prometheus/promci@v0.1.0 - uses: ./.github/promci/actions/build with: parallelism: 3 thread: ${{ matrix.thread }} golangci: name: golangci-lint runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Go uses: actions/setup-go@v5 with: go-version: '<1.22' - name: Lint uses: golangci/golangci-lint-action@v6.0.1 with: # Keep in sync with Makefile.common version: v1.56.2 # modified from the original as this repo still using master, insteead of main publish_master: name: Publish master branch artifacts runs-on: ubuntu-latest needs: [test, build] if: github.event_name == 'push' && github.event.ref == 'refs/heads/master' steps: - uses: actions/checkout@v4 - uses: prometheus/promci@v0.1.0 - uses: ./.github/promci/actions/publish_main with: docker_hub_organization: lusotycoon docker_hub_login: ${{ secrets.docker_hub_login }} docker_hub_password: ${{ secrets.docker_hub_password }} quay_io_organization: lusitaniae quay_io_login: ${{ secrets.quay_io_login }} quay_io_password: ${{ secrets.quay_io_password }} publish_release: name: Publish release arfefacts runs-on: ubuntu-latest needs: [test, build] if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') steps: - uses: actions/checkout@v4 - uses: prometheus/promci@v0.1.0 - uses: ./.github/promci/actions/publish_release with: docker_hub_organization: lusotycoon docker_hub_login: ${{ secrets.docker_hub_login }} docker_hub_password: ${{ secrets.docker_hub_password }} quay_io_organization: lusitaniae quay_io_login: ${{ secrets.quay_io_login }} quay_io_password: ${{ secrets.quay_io_password }} github_token: ${{ secrets.PROMBOT_GITHUB_TOKEN }} 07070100000006000081A4000000000000000000000001667C2A2400000027000000000000000000000000000000000000002100000000apache_exporter-1.0.8/.gitignore.idea/* bin/* vendor/ apache_exporter 07070100000007000081A4000000000000000000000001667C2A2400000086000000000000000000000000000000000000002400000000apache_exporter-1.0.8/.golangci.yml# Run only staticcheck for now. Additional linters will be enabled one-by-one. linters: enable: - staticcheck disable-all: true 07070100000008000081A4000000000000000000000001667C2A2400000291000000000000000000000000000000000000002100000000apache_exporter-1.0.8/.promu.ymlgo: # Whenever the Go version is updated here, # .github/workflows/ci.yml should also be updated. version: 1.22 # cgo: false repository: path: github.com/Lusitaniae/apache_exporter build: flags: -a -tags netgo ldflags: | -X github.com/prometheus/common/version.Version={{.Version}} -X github.com/prometheus/common/version.Revision={{.Revision}} -X github.com/prometheus/common/version.Branch={{.Branch}} -X github.com/prometheus/common/version.BuildUser={{user}}@{{host}} -X github.com/prometheus/common/version.BuildDate={{date "20060102-15:04:05"}} tarball: files: - LICENSE 07070100000009000081A4000000000000000000000001667C2A240000017C000000000000000000000000000000000000002000000000apache_exporter-1.0.8/.yamllint--- extends: default rules: braces: max-spaces-inside: 1 level: error brackets: max-spaces-inside: 1 level: error commas: disable comments: disable comments-indentation: disable document-start: disable indentation: spaces: consistent indent-sequences: consistent line-length: disable truthy: ignore: | .github/workflows/ci.yml 0707010000000A000081A4000000000000000000000001667C2A2400000076000000000000000000000000000000000000002300000000apache_exporter-1.0.8/CHANGELOG.md# 1.0.6 / 2024-01-30 * [FEATURE] Add UserAgent header ## 1.0.5 / 2023-12-22 * [BUGFIX] Add required changelog #182 0707010000000B000081A4000000000000000000000001667C2A2400000152000000000000000000000000000000000000002100000000apache_exporter-1.0.8/DockerfileARG ARCH="amd64" ARG OS="linux" FROM quay.io/prometheus/busybox-${OS}-${ARCH}:latest LABEL maintainer="https://github.com/Lusitaniae, https://github.com/roidelapluie" ARG ARCH="amd64" ARG OS="linux" COPY .build/${OS}-${ARCH}/apache_exporter /bin/apache_exporter EXPOSE 9117 USER nobody ENTRYPOINT [ "/bin/apache_exporter" ]0707010000000C000081A4000000000000000000000001667C2A2400000433000000000000000000000000000000000000001E00000000apache_exporter-1.0.8/LICENSEThe MIT License (MIT) Copyright (c) 2015 neezgee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0707010000000D000081A4000000000000000000000001667C2A240000052F000000000000000000000000000000000000001F00000000apache_exporter-1.0.8/Makefile# Copyright 2015 The Prometheus Authors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Needs to be defined before including Makefile.common to auto-generate targets DOCKER_ARCHS ?= amd64 armv7 arm64 ppc64le s390x DOCKER_IMAGE_NAME ?= apache-exporter all:: vet checkmetrics common-all include Makefile.common PROMETHEUS_VERSION=2.50.1 PROMTOOL ?= /tmp/prometheus-$(PROMETHEUS_VERSION).linux-amd64/promtool .PHONY: checkmetrics checkmetrics: @echo ">> checking metrics for correctness" if ! test -x $(PROMTOOL); then curl -sL -o - https://github.com/prometheus/prometheus/releases/download/v$(PROMETHEUS_VERSION)/prometheus-$(PROMETHEUS_VERSION).linux-amd64.tar.gz | tar -C /tmp -xzf - prometheus-$(PROMETHEUS_VERSION).linux-amd64/promtool; fi for file in test/*.metrics; do $(PROMTOOL) check metrics < $$file || exit 1; done 0707010000000E000081A4000000000000000000000001667C2A2400002954000000000000000000000000000000000000002600000000apache_exporter-1.0.8/Makefile.common# Copyright 2018 The Prometheus Authors # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # A common Makefile that includes rules to be reused in different prometheus projects. # !!! Open PRs only against the prometheus/prometheus/Makefile.common repository! # Example usage : # Create the main Makefile in the root project directory. # include Makefile.common # customTarget: # @echo ">> Running customTarget" # # Ensure GOBIN is not set during build so that promu is installed to the correct path unexport GOBIN GO ?= go GOFMT ?= $(GO)fmt FIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH))) GOOPTS ?= GOHOSTOS ?= $(shell $(GO) env GOHOSTOS) GOHOSTARCH ?= $(shell $(GO) env GOHOSTARCH) GO_VERSION ?= $(shell $(GO) version) GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') GOVENDOR := GO111MODULE := ifeq (, $(PRE_GO_111)) ifneq (,$(wildcard go.mod)) # Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI). GO111MODULE := on ifneq (,$(wildcard vendor)) # Always use the local vendor/ directory to satisfy the dependencies. GOOPTS := $(GOOPTS) -mod=vendor endif endif else ifneq (,$(wildcard go.mod)) ifneq (,$(wildcard vendor)) $(warning This repository requires Go >= 1.11 because of Go modules) $(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)') endif else # This repository isn't using Go modules (yet). GOVENDOR := $(FIRST_GOPATH)/bin/govendor endif endif PROMU := $(FIRST_GOPATH)/bin/promu pkgs = ./... ifeq (arm, $(GOHOSTARCH)) GOHOSTARM ?= $(shell GOARM= $(GO) env GOARM) GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM) else GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH) endif GOTEST := $(GO) test GOTEST_DIR := ifneq ($(CIRCLE_JOB),) ifneq ($(shell which gotestsum),) GOTEST_DIR := test-results GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml -- endif endif PROMU_VERSION ?= 0.13.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= # Keep in sync .github/workflows/ci.yaml GOLANGCI_LINT_VERSION ?= v1.56.2 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386)) # If we're in CI and there is an Actions file, that means the linter # is being run in Actions, so we don't need to run it here. ifeq (,$(CIRCLE_JOB)) GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint else ifeq (,$(wildcard .github/workflows/golangci-lint.yml)) GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint endif endif endif PREFIX ?= $(shell pwd) BIN_DIR ?= $(shell pwd) DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD)) DOCKERFILE_PATH ?= ./Dockerfile DOCKERBUILD_CONTEXT ?= ./ DOCKER_REPO ?= prom DOCKER_ARCHS ?= amd64 BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) TAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS)) ifeq ($(GOHOSTARCH),amd64) ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows)) # Only supported on amd64 test-flags := -race endif endif # This rule is used to forward a target like "build" to "common-build". This # allows a new "build" target to be defined in a Makefile which includes this # one and override "common-build" without override warnings. %: common-% ; .PHONY: common-all common-all: precheck style check_license lint yamllint unused build test .PHONY: common-style common-style: @echo ">> checking code style" @fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \ if [ -n "$${fmtRes}" ]; then \ echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \ echo "Please ensure you are using $$($(GO) version) for formatting code."; \ exit 1; \ fi .PHONY: common-check_license common-check_license: @echo ">> checking license header" @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \ awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \ done); \ if [ -n "$${licRes}" ]; then \ echo "license header checking failed:"; echo "$${licRes}"; \ exit 1; \ fi .PHONY: common-deps common-deps: @echo ">> getting dependencies" ifdef GO111MODULE GO111MODULE=$(GO111MODULE) $(GO) mod download else $(GO) get $(GOOPTS) -t ./... endif .PHONY: update-go-deps update-go-deps: @echo ">> updating Go dependencies" @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ $(GO) get -d $$m; \ done GO111MODULE=$(GO111MODULE) $(GO) mod tidy ifneq (,$(wildcard vendor)) GO111MODULE=$(GO111MODULE) $(GO) mod vendor endif .PHONY: common-test-short common-test-short: $(GOTEST_DIR) @echo ">> running short tests" GO111MODULE=$(GO111MODULE) $(GOTEST) -short $(GOOPTS) $(pkgs) .PHONY: common-test common-test: $(GOTEST_DIR) @echo ">> running all tests" GO111MODULE=$(GO111MODULE) $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) $(GOTEST_DIR): @mkdir -p $@ .PHONY: common-format common-format: @echo ">> formatting code" GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs) .PHONY: common-vet common-vet: @echo ">> vetting code" GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs) .PHONY: common-lint common-lint: $(GOLANGCI_LINT) ifdef GOLANGCI_LINT @echo ">> running golangci-lint" ifdef GO111MODULE # 'go list' needs to be executed before staticcheck to prepopulate the modules cache. # Otherwise staticcheck might fail randomly for some reason not yet explained. GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null GO111MODULE=$(GO111MODULE) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) else $(GOLANGCI_LINT) run $(pkgs) endif endif .PHONY: common-yamllint common-yamllint: @echo ">> running yamllint on all YAML files in the repository" ifeq (, $(shell which yamllint)) @echo "yamllint not installed so skipping" else yamllint . endif # For backward-compatibility. .PHONY: common-staticcheck common-staticcheck: lint .PHONY: common-unused common-unused: $(GOVENDOR) ifdef GOVENDOR @echo ">> running check for unused packages" @$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages' else ifdef GO111MODULE @echo ">> running check for unused/missing packages in go.mod" GO111MODULE=$(GO111MODULE) $(GO) mod tidy ifeq (,$(wildcard vendor)) @git diff --exit-code -- go.sum go.mod else @echo ">> running check for unused packages in vendor/" GO111MODULE=$(GO111MODULE) $(GO) mod vendor @git diff --exit-code -- go.sum go.mod vendor/ endif endif endif .PHONY: common-build common-build: promu @echo ">> building binaries" GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) .PHONY: common-tarball common-tarball: promu @echo ">> building release tarball" $(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR) .PHONY: common-docker $(BUILD_DOCKER_ARCHS) common-docker: $(BUILD_DOCKER_ARCHS) $(BUILD_DOCKER_ARCHS): common-docker-%: docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" \ -f $(DOCKERFILE_PATH) \ --build-arg ARCH="$*" \ --build-arg OS="linux" \ $(DOCKERBUILD_CONTEXT) .PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS) common-docker-publish: $(PUBLISH_DOCKER_ARCHS) $(PUBLISH_DOCKER_ARCHS): common-docker-publish-%: docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION))) .PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS) common-docker-tag-latest: $(TAG_DOCKER_ARCHS) $(TAG_DOCKER_ARCHS): common-docker-tag-latest-%: docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest" docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)" .PHONY: common-docker-manifest common-docker-manifest: DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(DOCKER_IMAGE_TAG)) DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)" .PHONY: promu promu: $(PROMU) $(PROMU): $(eval PROMU_TMP := $(shell mktemp -d)) curl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP) mkdir -p $(FIRST_GOPATH)/bin cp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu rm -r $(PROMU_TMP) .PHONY: proto proto: @echo ">> generating code from proto files" @./scripts/genproto.sh ifdef GOLANGCI_LINT $(GOLANGCI_LINT): mkdir -p $(FIRST_GOPATH)/bin curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \ | sed -e '/install -d/d' \ | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) endif ifdef GOVENDOR .PHONY: $(GOVENDOR) $(GOVENDOR): GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor endif .PHONY: precheck precheck:: define PRECHECK_COMMAND_template = precheck:: $(1)_precheck PRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1))) .PHONY: $(1)_precheck $(1)_precheck: @if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \ echo "Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?"; \ exit 1; \ fi endef 0707010000000F000081A4000000000000000000000001667C2A2400002128000000000000000000000000000000000000002000000000apache_exporter-1.0.8/README.md # Apache Exporter for Prometheus [![Build Status][buildstatus]][circleci] [![GitHub release](https://img.shields.io/github/release/Lusitaniae/apache_exporter.svg)][release] ![GitHub Downloads](https://img.shields.io/github/downloads/Lusitaniae/apache_exporter/total.svg) [![Docker Repository on Quay](https://quay.io/repository/Lusitaniae/apache-exporter/status)][quay] [![Docker Pulls](https://img.shields.io/docker/pulls/lusotycoon/apache-exporter.svg?maxAge=604800)][hub] Exports apache mod_status statistics via HTTP for Prometheus consumption. With working golang environment it can be built with `go get`. There is a [good article](https://machineperson.github.io/monitoring/2016/01/04/exporting-apache-metrics-to-prometheus.html) with build HOWTO and usage example. Help on flags: <pre> -h, --[no-]help Show context-sensitive help (also try --help-long and --help-man). --telemetry.endpoint="/metrics" Path under which to expose metrics. --scrape_uri="http://localhost/server-status/?auto" URI to apache stub status page. --host_override="" Override for HTTP Host header; empty string for no override. --[no-]insecure Ignore server certificate if using https. --custom_headers Adds custom headers to the collector. --[no-]web.systemd-socket Use systemd socket activation listeners instead of port listeners (Linux only). --web.listen-address=:9117 ... Addresses on which to expose metrics and web interface. Repeatable for multiple addresses. --web.config.file="" [EXPERIMENTAL] Path to configuration file that can enable TLS or authentication. --log.level=info Only log messages with the given severity or above. One of: [debug, info, warn, error] --log.format=logfmt Output format of log messages. One of: [logfmt, json] --[no-]version Show application version. </pre> Tested on Apache 2.2 and Apache 2.4. If your server-status page is secured by http auth, add the credentials to the scrape URL following this example: ``` http://user:password@localhost/server-status?auto ``` Override host name by runnning ``` ./apache_exporter --host_override=example.com ``` # Using Docker ## Use ```compose.yml``` - Requires Docker CE - Does not build from source, but rather pulls from registry only 1. Edit compose.yml if needed (Maybe to change server-status endpoint) 2. ```docker compose up``` ### OR ## Build the compatible binary To make sure that exporter binary created by build job is suitable to run on busybox environment, generate the binary using Makefile definition. Inside project directory run: ``` make ``` *Please be aware that binary generated using `go get` or `go build` with defaults may not work in busybox/alpine base images.* Another option is to use a docker go container to generate the binary. Pick an appropriate go image from https://hub.docker.com/_/golang. Inside the project directory run: ``` docker run --rm -v <project home>:/usr/local/go/src/github.com/Lusitaniae/apache_exporter -w /usr/local/go/src/github.com/Lusitaniae/apache_exporter <go docker image name> make ``` ## Build image Run the following commands from the project root directory. ``` docker build -t apache_exporter . ``` ## Run ``` docker run -d -p 9117:9117 apache_exporter \ --scrape_uri="https://your.server.com/server-status?auto" ``` ## Collectors Apache metrics: ``` # HELP apache_accesses_total Current total apache accesses (*) # TYPE apache_accesses_total counter # HELP apache_scoreboard Apache scoreboard statuses # TYPE apache_scoreboard gauge # HELP apache_sent_kilobytes_total Current total kbytes sent (*) # TYPE apache_sent_kilobytes_total counter # HELP apache_cpu_load CPU Load (*) # TYPE apache_cpu_load gauge # HELP apache_up Could the apache server be reached # TYPE apache_up gauge # HELP apache_uptime_seconds_total Current uptime in seconds (*) # TYPE apache_uptime_seconds_total counter # HELP apache_workers Apache worker statuses # TYPE apache_workers gauge # HELP apache_version Apache server version # TYPE apache_version gauge # HELP apache_duration_ms_total Total duration of all registered requests # TYPE apache_duration_ms_total gauge ``` Metrics marked '(*)' are only available if ExtendedStatus is On in apache webserver configuration. In version 2.3.6, loading mod_status will toggle ExtendedStatus On by default. ## FAQ Q. Can I change the Dockerfile? A. In short no, it's not meant for end users. It's part of the CI/CD pipeline in which promu is cross building the exporter for all architectures and packaging them into a Docker image. Q. Can I run this exporter on different architectures (ARM)? A. This exporter is cross compiled to all architectures using [promu](https://github.com/prometheus/promu) by running `promu crossbuild`. You can find the resulting artifacts in the release page (Github) or docker images in [Quay](https://quay.io/repository/Lusitaniae/apache-exporter) or [Docker](https://hub.docker.com/r/lusotycoon/apache-exporter/). Q. Is there a Grafana dashboard for this exporter? A. There's a 3rd party dashboard [here](https://grafana.com/dashboards/3894) which seems to work. Also [monitoring-mixin](https://monitoring.mixins.dev/) (dashboard+prometheus alerts) is available [here](https://github.com/grafana/jsonnet-libs/tree/master/apache-http-mixin). Q. Can you add additional metrics such as reqpersec, bytespersec and bytesperreq? A. In line with the [best practices](https://prometheus.io/docs/instrumenting/writing_exporters/#drop-less-useful-statistics), the exporter only provides the totals and you should derive rates using [PromQL](https://prometheus.io/docs/prometheus/latest/querying/basics/). > Like that: > - `ReqPerSec` : `rate(apache_accesses_total[5m])` > - `BytesPerSec`: `rate(apache_sent_kilobytes_total[5m])` > - `BytesPerReq`: BytesPerSec / ReqPerSec Q. Can I monitor multiple Apache instances? A. In line with the [best practices](https://prometheus.io/docs/instrumenting/writing_exporters/#deployment), the answer is no. *Each process being monitored should be accompanied by **one** exporter*. We suggest automating configuration and deployment using your favorite tools, e.g. Ansible/Chef/Kubernetes. Q. Its not working! Apache_up shows as 0 A. When apache_up reports 0 it means the exporter is running however it is not able to connect to Apache. Do you have this (or similar) configuration uncommented in your Apache instance? ``` <Location "/server-status"> SetHandler server-status Require host example.com </Location> ``` As documented at https://httpd.apache.org/docs/2.4/mod/mod_status.html Are you able to see the stats, if you run this from the Apache instance? `curl localhost/server-status?auto` If you run the exporter manually, do you see any errors? `./apache_exporter` Please include all this information if you still have issues when creating an issue. Q. There seem to be missing metrics! I can only see apache_up and apache_cpuload. A. Make sure that you add `?auto` at the end of the scrape_uri. ## TLS and basic authentication Apache Exporter supports TLS and basic authentication. This enables better control of the various HTTP endpoints. To use TLS and/or basic authentication, you need to pass a configuration file using the `--web.config` parameter (see above at help on flags). The format of the file is described [in the exporter-toolkit repository](https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md). Note that the TLS and basic authentication settings affect all HTTP endpoints: /metrics for scraping, /probe for probing, and the web UI. ## Author The exporter was originally created by [neezgee](https://github.com/neezgee). [buildstatus]: https://circleci.com/gh/Lusitaniae/apache_exporter/tree/master.svg?style=shield [quay]: https://quay.io/repository/Lusitaniae/apache-exporter [circleci]: https://circleci.com/gh/Lusitaniae/apache_exporter [hub]: https://hub.docker.com/r/lusotycoon/apache-exporter/ [release]: https://github.com/Lusitaniae/apache_exporter/releases/latest 07070100000010000081A4000000000000000000000001667C2A2400000006000000000000000000000000000000000000001E00000000apache_exporter-1.0.8/VERSION1.0.8 07070100000011000081A4000000000000000000000001667C2A2400000D88000000000000000000000000000000000000002900000000apache_exporter-1.0.8/apache_exporter.go// Copyright (c) 2015 neezgee // // Licensed under the MIT license: https://opensource.org/licenses/MIT // Permission is granted to use, copy, modify, and redistribute the work. // Full license information available in the project LICENSE file. // package main import ( "net/http" "os" "os/signal" "syscall" "time" "github.com/Lusitaniae/apache_exporter/collector" "github.com/alecthomas/kingpin/v2" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/common/promlog" "github.com/prometheus/common/promlog/flag" "github.com/prometheus/common/version" "github.com/prometheus/exporter-toolkit/web" "github.com/prometheus/exporter-toolkit/web/kingpinflag" ) var ( metricsEndpoint = kingpin.Flag("telemetry.endpoint", "Path under which to expose metrics.").Default("/metrics").String() scrapeURI = kingpin.Flag("scrape_uri", "URI to apache stub status page.").Default("http://localhost/server-status/?auto").String() hostOverride = kingpin.Flag("host_override", "Override for HTTP Host header; empty string for no override.").Default("").String() insecure = kingpin.Flag("insecure", "Ignore server certificate if using https.").Bool() toolkitFlags = kingpinflag.AddFlags(kingpin.CommandLine, ":9117") gracefulStop = make(chan os.Signal, 1) customHeaders = kingpin.Flag("custom_headers", "Adds custom headers to the collector.").StringMap() ) func main() { promlogConfig := &promlog.Config{} // Parse flags flag.AddFlags(kingpin.CommandLine, promlogConfig) kingpin.HelpFlag.Short('h') kingpin.Version(version.Print("apache_exporter")) kingpin.Parse() logger := promlog.New(promlogConfig) // listen to termination signals from the OS signal.Notify(gracefulStop, syscall.SIGTERM) signal.Notify(gracefulStop, syscall.SIGINT) signal.Notify(gracefulStop, syscall.SIGHUP) signal.Notify(gracefulStop, syscall.SIGQUIT) config := &collector.Config{ ScrapeURI: *scrapeURI, HostOverride: *hostOverride, Insecure: *insecure, CustomHeaders: *customHeaders, } exporter := collector.NewExporter(logger, config) prometheus.MustRegister(exporter) prometheus.MustRegister(version.NewCollector("apache_exporter")) level.Info(logger).Log("msg", "Starting apache_exporter", "version", version.Info()) level.Info(logger).Log("msg", "Build context", "build", version.BuildContext()) level.Info(logger).Log("msg", "Collect from: ", "scrape_uri", *scrapeURI) // listener for the termination signals from the OS go func() { level.Info(logger).Log("msg", "listening and wait for graceful stop") sig := <-gracefulStop level.Info(logger).Log("msg", "caught sig: %+v. Wait 2 seconds...", "sig", sig) time.Sleep(2 * time.Second) os.Exit(0) }() http.Handle(*metricsEndpoint, promhttp.Handler()) landingConfig := web.LandingConfig{ Name: "Apache Exporter", Description: "Prometheus exporter for Apache HTTP server metrics", Version: version.Info(), Links: []web.LandingLinks{ { Address: *metricsEndpoint, Text: "Metrics", }, }, } landingPage, err := web.NewLandingPage(landingConfig) if err != nil { level.Error(logger).Log("err", err) os.Exit(1) } http.Handle("/", landingPage) server := &http.Server{} if err := web.ListenAndServe(server, toolkitFlags, logger); err != nil { level.Error(logger).Log("err", err) os.Exit(1) } } 07070100000012000081A4000000000000000000000001667C2A240000217D000000000000000000000000000000000000002E00000000apache_exporter-1.0.8/apache_exporter_test.go// Copyright (c) 2015 neezgee // // Licensed under the MIT license: https://opensource.org/licenses/MIT // Permission is granted to use, copy, modify, and redistribute the work. // Full license information available in the project LICENSE file. // package main import ( "net/http" "net/http/httptest" "testing" "github.com/Lusitaniae/apache_exporter/collector" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/promlog" ) const ( apache24EventStatus = `localhost ServerVersion: Apache/2.4.23 (Unix) ServerMPM: event Server Built: Jul 29 2016 04:26:14 CurrentTime: Friday, 29-Jul-2016 14:06:15 UTC RestartTime: Friday, 29-Jul-2016 13:58:49 UTC ParentServerConfigGeneration: 1 ParentServerMPMGeneration: 0 ServerUptimeSeconds: 445 ServerUptime: 7 minutes 25 seconds Load1: 0.02 Load5: 0.02 Load15: 0.00 Total Accesses: 131 Total kBytes: 138 Total Duration: 12930 CPUUser: .25 CPUSystem: .15 CPUChildrenUser: 0 CPUChildrenSystem: 0 CPULoad: .0898876 Uptime: 445 ReqPerSec: .294382 BytesPerSec: 317.555 BytesPerReq: 1078.72 DurationPerReq: 98.7022 BusyWorkers: 1 IdleWorkers: 74 Processes: 5 Stopping: 0 ConnsTotal: 0 ConnsAsyncWriting: 0 ConnsAsyncKeepAlive: 0 ConnsAsyncClosing: 0 Scoreboard: _W___ ` apache24EventTLSStatus = `localhost ServerVersion: Apache/2.4.23 (Unix) ServerMPM: event Server Built: Jul 29 2016 04:26:14 CurrentTime: Friday, 29-Jul-2016 14:06:15 UTC RestartTime: Friday, 29-Jul-2016 13:58:49 UTC ParentServerConfigGeneration: 1 ParentServerMPMGeneration: 0 ServerUptimeSeconds: 445 ServerUptime: 7 minutes 25 seconds Load1: 0.02 Load5: 0.02 Load15: 0.00 Total Accesses: 131 Total kBytes: 138 Total Duration: 12930 CPUUser: .25 CPUSystem: .15 CPUChildrenUser: 0 CPUChildrenSystem: 0 CPULoad: .0898876 Uptime: 445 ReqPerSec: .294382 BytesPerSec: 317.555 BytesPerReq: 1078.72 DurationPerReq: 98.7022 BusyWorkers: 1 IdleWorkers: 74 Processes: 5 Stopping: 0 ConnsTotal: 0 ConnsAsyncWriting: 0 ConnsAsyncKeepAlive: 0 ConnsAsyncClosing: 0 Scoreboard: _W___ TLSSessionCacheStatus CacheType: SHMCB CacheSharedMemory: 512000 CacheCurrentEntries: 0 CacheSubcaches: 32 CacheIndexesPerSubcaches: 88 CacheIndexUsage: 0% CacheUsage: 0% CacheStoreCount: 0 CacheReplaceCount: 0 CacheExpireCount: 0 CacheDiscardCount: 0 CacheRetrieveHitCount: 0 CacheRetrieveMissCount: 1 CacheRemoveHitCount: 0 CacheRemoveMissCount: 0 ` apache24EventProxyStatus = `localhost ServerVersion: Apache/2.4.23 (Unix) ServerMPM: event Server Built: Jul 29 2016 04:26:14 CurrentTime: Friday, 29-Jul-2016 14:06:15 UTC RestartTime: Friday, 29-Jul-2016 13:58:49 UTC ParentServerConfigGeneration: 1 ParentServerMPMGeneration: 0 ServerUptimeSeconds: 445 ServerUptime: 7 minutes 25 seconds Load1: 0.02 Load5: 0.02 Load15: 0.00 Total Accesses: 131 Total kBytes: 138 Total Duration: 12930 CPUUser: .25 CPUSystem: .15 CPUChildrenUser: 0 CPUChildrenSystem: 0 CPULoad: .0898876 Uptime: 445 ReqPerSec: .294382 BytesPerSec: 317.555 BytesPerReq: 1078.72 DurationPerReq: 98.7022 BusyWorkers: 1 IdleWorkers: 74 Processes: 5 Stopping: 0 ConnsTotal: 0 ConnsAsyncWriting: 0 ConnsAsyncKeepAlive: 0 ConnsAsyncClosing: 0 Scoreboard: _W___ ProxyBalancer[0]Name: balancer://myproxy1 ProxyBalancer[0]Worker[0]Name: https://app-01:9143 ProxyBalancer[0]Worker[0]Status: Init Ok ProxyBalancer[0]Worker[0]Elected: 5808 ProxyBalancer[0]Worker[0]Busy: 0 ProxyBalancer[0]Worker[0]Sent: 5588K ProxyBalancer[0]Worker[0]Rcvd: 8335K ProxyBalancer[0]Worker[1]Name: https://app-02:9143 ProxyBalancer[0]Worker[1]Status: Init Ok ProxyBalancer[0]Worker[1]Elected: 5722 ProxyBalancer[0]Worker[1]Busy: 0 ProxyBalancer[0]Worker[1]Sent: 5167K ProxyBalancer[0]Worker[1]Rcvd: 8267K ProxyBalancer[0]Worker[2]Name: https://app-03:9143 ProxyBalancer[0]Worker[2]Status: Init Ok ProxyBalancer[0]Worker[2]Elected: 5842 ProxyBalancer[0]Worker[2]Busy: 0 ProxyBalancer[0]Worker[2]Sent: 5432K ProxyBalancer[0]Worker[2]Rcvd: 8367K ProxyBalancer[0]Worker[3]Name: https://app-04:9143 ProxyBalancer[0]Worker[3]Status: Init Ok ProxyBalancer[0]Worker[3]Elected: 5720 ProxyBalancer[0]Worker[3]Busy: 0 ProxyBalancer[0]Worker[3]Sent: 5576K ProxyBalancer[0]Worker[3]Rcvd: 8175K ProxyBalancer[1]Name: balancer://myproxy2 ProxyBalancer[1]Worker[0]Name: https://app-01:8143 ProxyBalancer[1]Worker[0]Status: Init Ok ProxyBalancer[1]Worker[0]Elected: 5808 ProxyBalancer[1]Worker[0]Busy: 0 ProxyBalancer[1]Worker[0]Sent: 5588K ProxyBalancer[1]Worker[0]Rcvd: 8335K ProxyBalancer[1]Worker[1]Name: https://app-02:8143 ProxyBalancer[1]Worker[1]Status: Init Ok ProxyBalancer[1]Worker[1]Elected: 5722 ProxyBalancer[1]Worker[1]Busy: 0 ProxyBalancer[1]Worker[1]Sent: 5167K ProxyBalancer[1]Worker[1]Rcvd: 8267K ` apache24WorkerStatus = `localhost ServerVersion: Apache/2.4.23 (Unix) OpenSSL/1.0.2h ServerMPM: worker Server Built: Aug 31 2016 10:54:08 CurrentTime: Thursday, 08-Sep-2016 15:09:32 CEST RestartTime: Thursday, 08-Sep-2016 15:08:07 CEST ParentServerConfigGeneration: 1 ParentServerMPMGeneration: 0 ServerUptimeSeconds: 85 ServerUptime: 1 minute 25 seconds Load1: 0.00 Load5: 0.01 Load15: 0.05 Total Accesses: 10 Total kBytes: 38 Total Duration: 12930 CPUUser: .05 CPUSystem: 0 CPUChildrenUser: 0 CPUChildrenSystem: 0 CPULoad: .0588235 Uptime: 85 ReqPerSec: .117647 BytesPerSec: 457.788 BytesPerReq: 3891.2 DurationPerReq: 1293.00 BusyWorkers: 2 IdleWorkers: 48 Scoreboard: _____R_______________________K____________________.................................................................................................... ` apache24PreforkStatus = `localhost ServerVersion: Apache/2.4.23 (Unix) OpenSSL/1.0.2h ServerMPM: prefork Server Built: Aug 31 2016 10:54:08 CurrentTime: Thursday, 08-Sep-2016 15:09:32 CEST RestartTime: Thursday, 08-Sep-2016 15:08:07 CEST ParentServerConfigGeneration: 1 ParentServerMPMGeneration: 0 ServerUptimeSeconds: 85 ServerUptime: 1 minute 25 seconds Load1: 0.00 Load5: 0.01 Load15: 0.05 Total Accesses: 10 Total kBytes: 38 Total Duration: 12930 CPUUser: .05 CPUSystem: 0 CPUChildrenUser: 0 CPUChildrenSystem: 0 CPULoad: .0588235 Uptime: 85 ReqPerSec: .117647 BytesPerSec: 457.788 BytesPerReq: 3891.2 DurationPerReq: 1293.00 BusyWorkers: 2 IdleWorkers: 48 Scoreboard: _____R_______________________K____________________.................................................................................................... ` apache22Status = `Total Accesses: 302311 Total kBytes: 1677830 CPULoad: 27.4052 Uptime: 45683 ReqPerSec: 6.61758 BytesPerSec: 37609.1 BytesPerReq: 5683.21 BusyWorkers: 2 IdleWorkers: 8 Scoreboard: _W_______K...................................................................................................................................................................................................................................................... ` metricCountApache22 = 19 metricCountApache24Event = 34 metricCountApache24EventTLS = 34 metricCountApache24EventProxy = 64 metricCountApache24Worker = 28 metricCountApache24Prefork = 28 ) func checkApacheStatus(t *testing.T, status string, metricCount int) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(status)) }) server := httptest.NewServer(handler) promlogConfig := &promlog.Config{} logger := promlog.New(promlogConfig) config := &collector.Config{ ScrapeURI: server.URL, HostOverride: "", Insecure: false, CustomHeaders: map[string]string{"Cookie": "A test cookie"}, } e := collector.NewExporter(logger, config) ch := make(chan prometheus.Metric) go func() { defer close(ch) e.Collect(ch) }() for i := 1; i <= metricCount; i++ { m := <-ch if m == nil { t.Error("expected metric but got nil") } } extraMetrics := 0 for <-ch != nil { extraMetrics++ } if extraMetrics > 0 { t.Errorf("expected closed channel, got %d extra metrics", extraMetrics) } } func TestApache22Status(t *testing.T) { checkApacheStatus(t, apache22Status, metricCountApache22) } func TestApache24EventStatus(t *testing.T) { checkApacheStatus(t, apache24EventStatus, metricCountApache24Event) } func TestApache24EventTLSStatus(t *testing.T) { checkApacheStatus(t, apache24EventTLSStatus, metricCountApache24EventTLS) } func TestApache24EventProxyStatus(t *testing.T) { checkApacheStatus(t, apache24EventProxyStatus, metricCountApache24EventProxy) } func TestApache24WorkerStatus(t *testing.T) { checkApacheStatus(t, apache24WorkerStatus, metricCountApache24Worker) } func TestApache24PreforkStatus(t *testing.T) { checkApacheStatus(t, apache24PreforkStatus, metricCountApache24Prefork) } 07070100000013000041ED000000000000000000000002667C2A2400000000000000000000000000000000000000000000002000000000apache_exporter-1.0.8/collector07070100000014000081A4000000000000000000000001667C2A2400003C9C000000000000000000000000000000000000002D00000000apache_exporter-1.0.8/collector/collector.go// Copyright (c) 2015 neezgee // // Licensed under the MIT license: https://opensource.org/licenses/MIT // Permission is granted to use, copy, modify, and redistribute the work. // Full license information available in the project LICENSE file. // package collector import ( "bufio" "bytes" "crypto/tls" "fmt" "io" "net/http" "regexp" "strconv" "strings" "sync" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/version" ) const ( namespace = "apache" ) var ( // Regular expressions for matching proxy balancer status lines. reProxyBalName = regexp.MustCompile(`ProxyBalancer\[\d+\]Name`) reProxyBalWorker = regexp.MustCompile(`ProxyBalancer\[\d+\]Worker\[\d+\](\S+)`) ) type Exporter struct { URI string hostOverride string customHeaders map[string]string mutex sync.Mutex client *http.Client userAgent string up *prometheus.Desc scrapeFailures prometheus.Counter apacheVersion *prometheus.Desc apacheInfo *prometheus.GaugeVec generation *prometheus.GaugeVec load *prometheus.GaugeVec accessesTotal *prometheus.Desc kBytesTotal *prometheus.Desc durationTotal *prometheus.Desc cpuTotal *prometheus.Desc cpuload prometheus.Gauge uptime *prometheus.Desc workers *prometheus.GaugeVec processes *prometheus.GaugeVec connections *prometheus.GaugeVec scoreboard *prometheus.GaugeVec proxyBalancerStatus *prometheus.GaugeVec proxyBalancerElected *prometheus.Desc proxyBalancerBusy *prometheus.GaugeVec proxyBalancerReqSize *prometheus.Desc proxyBalancerRespSize *prometheus.Desc logger log.Logger } type Config struct { ScrapeURI string HostOverride string Insecure bool CustomHeaders map[string]string } func NewExporter(logger log.Logger, config *Config) *Exporter { return &Exporter{ URI: config.ScrapeURI, hostOverride: config.HostOverride, customHeaders: config.CustomHeaders, logger: logger, up: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "up"), "Could the apache server be reached", nil, nil), scrapeFailures: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: namespace, Name: "exporter_scrape_failures_total", Help: "Number of errors while scraping apache.", }), apacheVersion: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "version"), "Apache server version", nil, nil), apacheInfo: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "info", Help: "Apache version information", }, []string{"version", "mpm"}, ), generation: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "generation", Help: "Apache restart generation", }, []string{"type"}, ), load: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "load", Help: "Apache server load", }, []string{"interval"}, ), accessesTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "accesses_total"), "Current total apache accesses (*)", nil, nil), kBytesTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "sent_kilobytes_total"), "Current total kbytes sent (*)", nil, nil), durationTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "duration_ms_total"), "Total duration of all registered requests in ms", nil, nil), cpuTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "cpu_time_ms_total"), "Apache CPU time", []string{"type"}, nil, ), cpuload: prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "cpuload", Help: "The current percentage CPU used by each worker and in total by all workers combined (*)", }), uptime: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "uptime_seconds_total"), "Current uptime in seconds (*)", nil, nil), workers: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "workers", Help: "Apache worker statuses", }, []string{"state"}, ), processes: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "processes", Help: "Apache process count", }, []string{"state"}, ), connections: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "connections", Help: "Apache connection statuses", }, []string{"state"}, ), scoreboard: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "scoreboard", Help: "Apache scoreboard statuses", }, []string{"state"}, ), proxyBalancerStatus: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "proxy_balancer_status", Help: "Apache Proxy Balancer Statuses", }, []string{"balancer", "worker", "status"}, ), proxyBalancerElected: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "proxy_balancer_accesses_total"), "Apache Proxy Balancer Request Count", []string{"balancer", "worker"}, nil, ), proxyBalancerBusy: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "proxy_balancer_busy", Help: "Apache Proxy Balancer Active Requests", }, []string{"balancer", "worker"}, ), proxyBalancerReqSize: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "proxy_balancer_request_kbytes_total"), "Apache Proxy Balancer Request Count", []string{"balancer", "worker"}, nil, ), proxyBalancerRespSize: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "proxy_balancer_response_kbytes_total"), "Apache Proxy Balancer Request Count", []string{"balancer", "worker"}, nil, ), client: &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: config.Insecure}, }, }, userAgent: fmt.Sprintf("Prometheus-Apache-Exporter/%s", version.Version), } } // Describe implements Prometheus.Collector. func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { ch <- e.up e.scrapeFailures.Describe(ch) ch <- e.apacheVersion e.apacheInfo.Describe(ch) e.generation.Describe(ch) e.load.Describe(ch) ch <- e.accessesTotal ch <- e.kBytesTotal ch <- e.durationTotal ch <- e.cpuTotal e.cpuload.Describe(ch) ch <- e.uptime e.workers.Describe(ch) e.processes.Describe(ch) e.connections.Describe(ch) e.scoreboard.Describe(ch) e.proxyBalancerStatus.Describe(ch) ch <- e.proxyBalancerElected e.proxyBalancerBusy.Describe(ch) ch <- e.proxyBalancerReqSize ch <- e.proxyBalancerRespSize } // Split colon separated string into two fields func splitkv(s string) (string, string) { if len(s) == 0 { return s, s } slice := strings.SplitN(s, ":", 2) if len(slice) == 1 { return slice[0], "" } return strings.TrimSpace(slice[0]), strings.TrimSpace(slice[1]) } var scoreboardLabelMap = map[string]string{ "_": "idle", "S": "startup", "R": "read", "W": "reply", "K": "keepalive", "D": "dns", "C": "closing", "L": "logging", "G": "graceful_stop", "I": "idle_cleanup", ".": "open_slot", } func (e *Exporter) updateScoreboard(scoreboard string) { e.scoreboard.Reset() for _, v := range scoreboardLabelMap { e.scoreboard.WithLabelValues(v) } for _, worker_status := range scoreboard { s := string(worker_status) label, ok := scoreboardLabelMap[s] if !ok { label = s } e.scoreboard.WithLabelValues(label).Inc() } } func (e *Exporter) collect(ch chan<- prometheus.Metric) error { req, err := http.NewRequest(http.MethodGet, e.URI, nil) if err != nil { return fmt.Errorf("error building scraping request: %w", err) } if e.hostOverride != "" { req.Host = e.hostOverride } for k, v := range e.customHeaders { req.Header.Add(k, v) } req.Header.Set("User-Agent", e.userAgent) resp, err := e.client.Do(req) if err != nil { ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 0) return fmt.Errorf("error scraping Apache: %w", err) } ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 1) data, err := io.ReadAll(resp.Body) resp.Body.Close() if resp.StatusCode != http.StatusOK { if err != nil { data = []byte(err.Error()) } return fmt.Errorf("status %s (%d): %s", resp.Status, resp.StatusCode, data) } connectionInfo := false version := "UNKNOWN" mpm := "UNKNOWN" balancerName := "UNKNOWN" workerName := "UNKNOWN" cpuUser := 0.0 cpuSystem := 0.0 cpuFound := false e.proxyBalancerStatus.Reset() e.proxyBalancerBusy.Reset() scanner := bufio.NewScanner(bytes.NewReader(data)) for scanner.Scan() { key, v := splitkv(scanner.Text()) if err != nil { continue } switch { case key == "ServerVersion": version = v tmpstr := strings.Split(v, "/")[1] tmpstr = strings.Split(tmpstr, " ")[0] vparts := strings.Split(tmpstr, ".") tmpstr = fmt.Sprintf("%s.%02s%03s", vparts[0], vparts[1], vparts[2]) val, err := strconv.ParseFloat(tmpstr, 64) if err != nil { return err } ch <- prometheus.MustNewConstMetric(e.apacheVersion, prometheus.GaugeValue, val) case key == "ServerMPM": mpm = v case key == "ParentServerConfigGeneration": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.generation.WithLabelValues("config").Set(val) case key == "ParentServerMPMGeneration": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.generation.WithLabelValues("mpm").Set(val) case key == "Load1": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.load.WithLabelValues("1min").Set(val) case key == "Load5": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.load.WithLabelValues("5min").Set(val) case key == "Load15": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.load.WithLabelValues("15min").Set(val) case key == "Total Accesses": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } ch <- prometheus.MustNewConstMetric(e.accessesTotal, prometheus.CounterValue, val) case key == "Total kBytes": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } ch <- prometheus.MustNewConstMetric(e.kBytesTotal, prometheus.CounterValue, val) case key == "Total Duration": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } ch <- prometheus.MustNewConstMetric(e.durationTotal, prometheus.CounterValue, val) case key == "CPUUser": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } cpuUser += val cpuFound = true case key == "CPUChildrenUser": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } cpuUser += val cpuFound = true case key == "CPUSystem": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } cpuSystem += val cpuFound = true case key == "CPUChildrenSystem": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } cpuSystem += val cpuFound = true case key == "CPULoad": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.cpuload.Set(val) case key == "Uptime": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } ch <- prometheus.MustNewConstMetric(e.uptime, prometheus.CounterValue, val) case key == "BusyWorkers": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.workers.WithLabelValues("busy").Set(val) case key == "IdleWorkers": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.workers.WithLabelValues("idle").Set(val) case key == "Processes": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.processes.WithLabelValues("all").Set(val) case key == "Stopping": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.processes.WithLabelValues("stopping").Set(val) case key == "ConnsTotal": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.connections.WithLabelValues("total").Set(val) connectionInfo = true case key == "ConnsAsyncWriting": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.connections.WithLabelValues("writing").Set(val) connectionInfo = true case key == "ConnsAsyncKeepAlive": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.connections.WithLabelValues("keepalive").Set(val) connectionInfo = true case key == "ConnsAsyncClosing": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.connections.WithLabelValues("closing").Set(val) connectionInfo = true case key == "Scoreboard": e.updateScoreboard(v) e.scoreboard.Collect(ch) //ProxyBalancer[0]Name: balancer://sid2021 //ProxyBalancer[0]Worker[0]Name: https://z-app-01:9143 //ProxyBalancer[0]Worker[0]Status: Init Ok //ProxyBalancer[0]Worker[0]Elected: 5808 //... case reProxyBalName.MatchString(key): balancerName = v case reProxyBalWorker.MatchString(key): key := reProxyBalWorker.FindStringSubmatch(key)[1] switch key { case "Name": workerName = v case "Status": e.proxyBalancerStatus.WithLabelValues(balancerName, workerName, v).Set(1) case "Elected": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } ch <- prometheus.MustNewConstMetric(e.proxyBalancerElected, prometheus.CounterValue, val, balancerName, workerName) case "Busy": val, err := strconv.ParseFloat(v, 64) if err != nil { return err } e.proxyBalancerBusy.WithLabelValues(balancerName, workerName).Set(val) case "Sent": val, err := strconv.ParseFloat(strings.TrimRight(v, "kK"), 64) if err != nil { return err } ch <- prometheus.MustNewConstMetric(e.proxyBalancerReqSize, prometheus.CounterValue, val, balancerName, workerName) case "Rcvd": val, err := strconv.ParseFloat(strings.TrimRight(v, "kK"), 64) if err != nil { return err } ch <- prometheus.MustNewConstMetric(e.proxyBalancerRespSize, prometheus.CounterValue, val, balancerName, workerName) } } } if cpuFound { ch <- prometheus.MustNewConstMetric(e.cpuTotal, prometheus.CounterValue, 1000*cpuUser, "user") ch <- prometheus.MustNewConstMetric(e.cpuTotal, prometheus.CounterValue, 1000*cpuSystem, "system") } e.apacheInfo.WithLabelValues(version, mpm).Set(1) e.apacheInfo.Collect(ch) e.generation.Collect(ch) e.load.Collect(ch) e.cpuload.Collect(ch) e.workers.Collect(ch) e.processes.Collect(ch) if connectionInfo { e.connections.Collect(ch) } e.proxyBalancerStatus.Collect(ch) e.proxyBalancerBusy.Collect(ch) return nil } // Collect implements Prometheus.Collector. func (e *Exporter) Collect(ch chan<- prometheus.Metric) { e.mutex.Lock() // To protect metrics from concurrent collects. defer e.mutex.Unlock() if err := e.collect(ch); err != nil { level.Error(e.logger).Log("msg", "Error scraping Apache:", "err", err) e.scrapeFailures.Inc() e.scrapeFailures.Collect(ch) } } 07070100000015000081A4000000000000000000000001667C2A2400000194000000000000000000000000000000000000002200000000apache_exporter-1.0.8/compose.ymlname: apache_exporter services: apache_exporter: image: lusotycoon/apache-exporter container_name: apache_exporter privileged: true ports: - mode: ingress target: 9117 published: "9117" protocol: tcp restart: unless-stopped extra_hosts: - "localhost:127.17.0.1" entrypoint: /bin/apache_exporter --scrape_uri="http://172.17.0.1/server-status?auto" 07070100000016000081A4000000000000000000000001667C2A24000004E8000000000000000000000000000000000000001D00000000apache_exporter-1.0.8/go.modmodule github.com/Lusitaniae/apache_exporter go 1.19 require ( github.com/alecthomas/kingpin/v2 v2.4.0 github.com/go-kit/log v0.2.1 github.com/prometheus/client_golang v1.19.1 github.com/prometheus/common v0.48.0 github.com/prometheus/exporter-toolkit v0.11.0 ) require ( github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.23.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) 07070100000017000081A4000000000000000000000001667C2A2400001B0D000000000000000000000000000000000000001D00000000apache_exporter-1.0.8/go.sumgithub.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 07070100000018000041ED000000000000000000000002667C2A2400000000000000000000000000000000000000000000001B00000000apache_exporter-1.0.8/test07070100000019000081A4000000000000000000000001667C2A24000019C7000000000000000000000000000000000000002D00000000apache_exporter-1.0.8/test/not_found.metrics# HELP apache_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, and goversion from which apache_exporter was built. # TYPE apache_exporter_build_info gauge apache_exporter_build_info{branch="",goversion="go1.16.4",revision="",version=""} 1 # HELP apache_exporter_scrape_failures_total Number of errors while scraping apache. # TYPE apache_exporter_scrape_failures_total counter apache_exporter_scrape_failures_total 1 # HELP apache_up Could the apache server be reached # TYPE apache_up gauge apache_up 0 # HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 0 go_gc_duration_seconds{quantile="0.25"} 0 go_gc_duration_seconds{quantile="0.5"} 0 go_gc_duration_seconds{quantile="0.75"} 0 go_gc_duration_seconds{quantile="1"} 0 go_gc_duration_seconds_sum 0 go_gc_duration_seconds_count 0 # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge go_goroutines 9 # HELP go_info Information about the Go environment. # TYPE go_info gauge go_info{version="go1.16.4"} 1 # HELP go_memstats_alloc_bytes Number of bytes allocated and still in use. # TYPE go_memstats_alloc_bytes gauge go_memstats_alloc_bytes 744464 # 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 744464 # 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 4157 # HELP go_memstats_frees_total Total number of frees. # TYPE go_memstats_frees_total counter go_memstats_frees_total 176 # HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since the program started. # TYPE go_memstats_gc_cpu_fraction gauge go_memstats_gc_cpu_fraction 0 # 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 4.017656e+06 # 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 744464 # 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 6.4987136e+07 # 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 1.662976e+06 # HELP go_memstats_heap_objects Number of allocated objects. # TYPE go_memstats_heap_objects gauge go_memstats_heap_objects 2933 # 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 6.4954368e+07 # 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 6.6650112e+07 # 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 0 # HELP go_memstats_lookups_total Total number of pointer lookups. # TYPE go_memstats_lookups_total counter go_memstats_lookups_total 0 # HELP go_memstats_mallocs_total Total number of mallocs. # TYPE go_memstats_mallocs_total counter go_memstats_mallocs_total 3109 # 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 14400 # 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 46648 # 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.473924e+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 978395 # 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 458752 # 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 458752 # HELP go_memstats_sys_bytes Number of bytes obtained from system. # TYPE go_memstats_sys_bytes gauge go_memstats_sys_bytes 7.2174608e+07 # HELP go_threads Number of OS threads created. # TYPE go_threads gauge go_threads 9 # 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 # 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 9 # HELP process_resident_memory_bytes Resident memory size in bytes. # TYPE process_resident_memory_bytes gauge process_resident_memory_bytes 9.986048e+06 # 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.62290564579e+09 # HELP process_virtual_memory_bytes Virtual memory size in bytes. # TYPE process_virtual_memory_bytes gauge process_virtual_memory_bytes 1.184079872e+09 # HELP process_virtual_memory_max_bytes Maximum amount of virtual memory available in bytes. # TYPE process_virtual_memory_max_bytes gauge process_virtual_memory_max_bytes -1 # HELP promhttp_metric_handler_requests_in_flight Current number of scrapes being served. # TYPE promhttp_metric_handler_requests_in_flight gauge promhttp_metric_handler_requests_in_flight 1 # HELP promhttp_metric_handler_requests_total Total number of scrapes by HTTP status code. # TYPE promhttp_metric_handler_requests_total counter promhttp_metric_handler_requests_total{code="200"} 0 promhttp_metric_handler_requests_total{code="500"} 0 promhttp_metric_handler_requests_total{code="503"} 0 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!144 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor