diff --git a/.circleci/config.yml b/.circleci/config.yml index 5e59a88..3232389 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,23 +1,35 @@ -# Golang CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-go/ for more details +defaults: &defaults + working_directory: /go/src/github.com/hipages/php-fpm_exporter + version: 2 jobs: - build: + test: + <<: *defaults docker: - image: circleci/golang:1.9 - working_directory: /go/src/github.com/hipages/php-fpm_exporter steps: - checkout - run: curl -L -s https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 -o /go/bin/dep && chmod +x /go/bin/dep - run: dep ensure -vendor-only - run: go test -v ./... - deploy: + lint: + <<: *defaults + docker: + - image: circleci/golang:1.9 + steps: + - checkout + - run: curl -L -s https://github.com/golang/dep/releases/download/v0.4.1/dep-linux-amd64 -o /go/bin/dep && chmod +x /go/bin/dep + - run: dep ensure -vendor-only + - run: curl -L -s https://github.com/alecthomas/gometalinter/releases/download/v2.0.5/gometalinter-2.0.5-linux-amd64.tar.gz | tar xvfz - -C /go/bin/ --strip 1 +# - run: gometalinter --disable-all --enable=errcheck --enable=vet --enable=vetshadow --vendor ./... + - run: gometalinter --disable-all --enable=vet --enable=vetshadow --vendor ./... + + deploy: + <<: *defaults docker: - image: circleci/golang:1.9 - working_directory: /go/src/github.com/hipages/php-fpm_exporter steps: - checkout - setup_remote_docker: @@ -31,13 +43,17 @@ workflows: version: 2 build-n-deploy: jobs: - - build: + - test: + filters: + tags: + only: /^v.*/ + - lint: filters: tags: only: /^v.*/ - deploy: requires: - - build + - test filters: branches: ignore: /.*/ diff --git a/README.md b/README.md index 2b8b8f3..7bf3b1e 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ The `server` command runs the server required for prometheus to retrieve the sta | `--web.listen-address` | Address on which to expose metrics and web interface. | `PHP_FPM_WEB_LISTEN_ADDRESS` | [`:9253`](https://github.com/prometheus/prometheus/wiki/Default-port-allocations) | | `--web.telemetry-path` | Path under which to expose metrics. | `PHP_FPM_WEB_TELEMETRY_PATH` | `/metrics` | | `--phpfpm.scrape-uri` | FastCGI address, e.g. unix:///tmp/php.sock;/status or tcp://127.0.0.1:9000/status | `PHP_FPM_SCRAPE_URI` | `tcp://127.0.0.1:9000/status` | -| `--log.level` | Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal] (default "error") | PHP_FPM_LOG_LEVEL | info | +| `--phpfpm.fix-process-count` | Enable to calculate process numbers via php-fpm_exporter since PHP-FPM sporadically reports wrong active/idle/total process numbers. | `PHP_FPM_FIX_PROCESS_COUNT`| `false` | +| `--log.level` | Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal] (default "error") | `PHP_FPM_LOG_LEVEL` | info | ### CLI Examples @@ -54,6 +55,11 @@ The `server` command runs the server required for prometheus to retrieve the sta php-fpm_exporter server --phpfpm.scrape-uri tcp://127.0.0.1:9000/status,tcp://127.0.0.1:9001/status ``` +* Run as server and enable process count fix via environment variable: + ``` + PHP_FPM_FIX_PROCESS_COUNT=1 go run main.go server --web.listen-address ":12345" --log.level=debug + ``` + ### Docker Examples * Run docker manually @@ -75,6 +81,8 @@ The `server` command runs the server required for prometheus to retrieve the sta [![asciicast](https://asciinema.org/a/1msR8nqAsFdHzROosUb7PiHvf.png)](https://asciinema.org/a/1msR8nqAsFdHzROosUb7PiHvf) +### Kubernetes Example + ## Metrics collected ``` @@ -94,6 +102,12 @@ The `server` command runs the server required for prometheus to retrieve the sta # TYPE phpfpm_max_children_reached counter # HELP phpfpm_max_listen_queue The maximum number of requests in the queue of pending connections since FPM has started. # TYPE phpfpm_max_listen_queue counter +# HELP phpfpm_process_last_request_cpu +# TYPE phpfpm_process_last_request_cpu gauge +# HELP phpfpm_process_last_request_memory +# TYPE phpfpm_process_last_request_memory gauge +# HELP phpfpm_process_requests +# TYPE phpfpm_process_requests counter # HELP phpfpm_scrape_failures The number of failures scraping from PHP-FPM. # TYPE phpfpm_scrape_failures counter # HELP phpfpm_slow_requests The number of requests that exceeded your 'request_slowlog_timeout' value. @@ -127,4 +141,4 @@ Before starting any work, please either comment on an existing issue, or file a * [bakins/php-fpm-exporter](https://github.com/bakins/php-fpm-exporter) * [peakgames/php-fpm-prometheus](https://github.com/peakgames/php-fpm-prometheus) -* [craigmj/phpfpm_exporter](https://github.com/craigmj/phpfpm_exporter) \ No newline at end of file +* [craigmj/phpfpm_exporter](https://github.com/craigmj/phpfpm_exporter) diff --git a/cmd/get.go b/cmd/get.go index 7ecbc20..94d44db 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -16,11 +16,12 @@ package cmd import ( "encoding/json" "fmt" + "time" + "github.com/davecgh/go-spew/spew" "github.com/gosuri/uitable" "github.com/hipages/php-fpm_exporter/phpfpm" "github.com/spf13/cobra" - "time" ) // Configuration variables @@ -44,7 +45,9 @@ var getCmd = &cobra.Command{ pm.Add(uri) } - pm.Update() + if err := pm.Update(); err != nil { + log.Fatal("Could not update pool.", err) + } switch output { case "json": diff --git a/cmd/root.go b/cmd/root.go index d19e5c4..9899ccc 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -101,3 +101,15 @@ func initLogger() { log.SetLevel(lvl) } + +func mapEnvVars(envs map[string]string, cmd *cobra.Command) { + for env, flag := range envs { + flag := cmd.Flags().Lookup(flag) + flag.Usage = fmt.Sprintf("%v [env %v]", flag.Usage, env) + if value := os.Getenv(env); value != "" { + if err := flag.Value.Set(value); err != nil { + log.Error(err) + } + } + } +} diff --git a/cmd/server.go b/cmd/server.go index 3e15f38..4cb2beb 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -15,15 +15,15 @@ package cmd import ( "context" - "fmt" - "github.com/hipages/php-fpm_exporter/phpfpm" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/spf13/cobra" "net/http" "os" "os/signal" "time" + + "github.com/hipages/php-fpm_exporter/phpfpm" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/spf13/cobra" ) // Configuration variables @@ -102,7 +102,9 @@ to quickly create a Cobra application.`, defer cancel() // Doesn't block if no connections, but will otherwise wait // until the timeout deadline. - srv.Shutdown(ctx) + if err := srv.Shutdown(ctx); err != nil { + log.Fatal("Error during shutdown", err) + } // Optionally, you could run srv.Shutdown in a goroutine and block on // <-ctx.Done() if your application should wait for other services // to finalize based on context cancellation. @@ -114,14 +116,6 @@ to quickly create a Cobra application.`, func init() { RootCmd.AddCommand(serverCmd) - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // serverCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: serverCmd.Flags().StringVar(&listeningAddress, "web.listen-address", ":9253", "Address on which to expose metrics and web interface.") serverCmd.Flags().StringVar(&metricsEndpoint, "web.telemetry-path", "/metrics", "Path under which to expose metrics.") serverCmd.Flags().StringSliceVar(&scrapeURIs, "phpfpm.scrape-uri", []string{"tcp://127.0.0.1:9000/status"}, "FastCGI address, e.g. unix:///tmp/php.sock;/status or tcp://127.0.0.1:9000/status") @@ -139,11 +133,5 @@ func init() { "PHP_FPM_FIX_PROCESS_COUNT": "phpfpm.fix-process-count", } - for env, flag := range envs { - flag := serverCmd.Flags().Lookup(flag) - flag.Usage = fmt.Sprintf("%v [env %v]", flag.Usage, env) - if value := os.Getenv(env); value != "" { - flag.Value.Set(value) - } - } + mapEnvVars(envs, serverCmd) } diff --git a/cmd/version.go b/cmd/version.go index 9cb124e..6ad7252 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -31,14 +31,4 @@ var versionCmd = &cobra.Command{ func init() { RootCmd.AddCommand(versionCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // versionCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } diff --git a/main.go b/main.go index 8fffe69..bb05034 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ package main import ( "fmt" + "github.com/hipages/php-fpm_exporter/cmd" ) diff --git a/phpfpm/exporter.go b/phpfpm/exporter.go index 69af823..08c0fb2 100644 --- a/phpfpm/exporter.go +++ b/phpfpm/exporter.go @@ -11,12 +11,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package phpfpm provides convenient access to PHP-FPM pool data package phpfpm import ( + "sync" + "github.com/prometheus/client_golang/prometheus" "github.com/speps/go-hashids" - "sync" ) const ( diff --git a/phpfpm/phpfpm.go b/phpfpm/phpfpm.go index 5a3f1a0..06f3cba 100644 --- a/phpfpm/phpfpm.go +++ b/phpfpm/phpfpm.go @@ -17,12 +17,13 @@ package phpfpm import ( "encoding/json" "fmt" - "github.com/tomasen/fcgi_client" "io/ioutil" "net/url" "strconv" "sync" "time" + + "github.com/tomasen/fcgi_client" ) // PoolProcessRequestIdle defines a process that is idle.