Skip to content

Commit

Permalink
✨ Add driver collector (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
chicobentojr authored and jamillosantos committed Jan 21, 2020
1 parent af7fb93 commit 6d0a676
Show file tree
Hide file tree
Showing 13 changed files with 1,551 additions and 10 deletions.
4 changes: 4 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ jobs:
build:
docker:
- image: lab259/go-circleci:1.12

- image: postgres:11-alpine
environment:
POSTGRES_DB: pg-test
steps:
- checkout
- restore_cache:
Expand Down
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ COVERDIR=$(CURDIR)/.cover
COVERAGEFILE=$(COVERDIR)/cover.out
COVERAGEREPORT=$(COVERDIR)/report.html

DOCKERCOMPOSETEST := docker-compose -f docker-compose-test.yml

test:
@ginkgo --failFast ./...
@go run github.com/onsi/ginkgo/ginkgo -r --failFast -requireSuite --randomizeAllSpecs --randomizeSuites --cover --trace --race -timeout=2m $(TARGET)

test-watch:
@ginkgo watch -cover -r ./...
Expand All @@ -28,4 +30,10 @@ vet:
fmt:
@go fmt ./...

.PHONY: test test-watch coverage coverage-ci coverage-html vet fmt
dco-test-up:
@${DOCKERCOMPOSETEST} up -d

dco-test-down:
@${DOCKERCOMPOSETEST} down --remove-orphans

.PHONY: test test-watch coverage coverage-ci coverage-html vet fmt dco-test-up dco-test-down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,34 @@ _All these metrics are provided by the `database/sql` package interface._
- Prefix `string`: That will add a prefix to the metrics names. So, for example, `db_max_open_connections` will become `db_PREFIX_max_open_connections`.


**database/sql/driver**

Given a driver name (e.g. `postgres`), you can create a collector by using `promsql.Register(opts)`.

The information provided by the collector will generate these metrics:

- db_query_total: The total number of queries processed.
- db_query_successful: The number of queries processed with success.
- db_query_failed: The number of queries processed with failure.
- db_transaction_total: The total number of transactions processed.
- db_transaction_successful: The number of transactions processed with success.
- db_transaction_failed: The number of transactions processed with failure.
- db_execution_total: The total number of executions processed.
- db_execution_successful: The number of executions processed with success.
- db_execution_failed: The number of executions processed with failure.

**opts: _promsql.DriverCollectorOpts**
- DriverName `string`: The base driver name that will be used by sql package (e.g. `postgres`, `mysql`)
- Prefix `string`: That will add a prefix to the metrics names. So, for example, `db_query_total` will become `db_PREFIX_query_total`.

### Running tests

In order to run the tests, spin up the :

```bash
make dco-test-up
```

In the `src/github.com/lab259/go-rscsrv-prometheus` directory, execute:

```bash
Expand Down
11 changes: 11 additions & 0 deletions docker-compose-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: '3.1'

services:

postgres:
image: postgres:11-alpine
environment:
POSTGRES_DB: pg-test
ports:
- 5432:5432
tmpfs: /var/lib/postgresql/data
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: '3.1'

services:

postgres:
image: postgres:11-alpine
environment:
POSTGRES_DB: db-example
ports:
- 5432:5432
tmpfs: /var/lib/postgresql/data
92 changes: 92 additions & 0 deletions examples/promsql/driver_collector/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package main

import (
"database/sql"
"fmt"
"log"
"time"

"github.com/lab259/go-rscsrv"
"github.com/lab259/go-rscsrv-prometheus/examples/promsql/driver_collector/services"
"github.com/lab259/go-rscsrv-prometheus/promhermes"
h "github.com/lab259/hermes"
"github.com/lab259/hermes/middlewares"
)

func main() {
serviceStarter := rscsrv.DefaultServiceStarter(
&services.DefaultDriverCollector,
&services.DefaultPromService,
)
if err := serviceStarter.Start(); err != nil {
panic(err)
}

router := h.DefaultRouter()
router.Use(middlewares.RecoverableMiddleware, middlewares.LoggingMiddleware)
router.Get("/metrics", promhermes.Handler(&services.DefaultPromService))

app := h.NewApplication(h.ApplicationConfig{
ServiceStarter: serviceStarter,
HTTP: h.FasthttpServiceConfiguration{
Bind: ":3000",
},
}, router)

log.Println("Go to http://localhost:3000/metrics")

// Updating metrics
go func() {
psqlInfo := fmt.Sprintf("user=postgres password=postgres dbname=pg-test sslmode=disable")
db, err := sql.Open(services.DefaultDriverCollector.DriverName, psqlInfo)
if err != nil {
panic(err)
}
defer db.Close()

err = db.Ping()
if err != nil {
panic(err)
}

db.Exec(`DROP TABLE users`)

_, err = db.Exec(`
CREATE TABLE users (
id int NOT NULL PRIMARY KEY,
name text NOT NULL
);
INSERT INTO users (id, name)
VALUES (1, 'john')
`)
if err != nil {
panic(err)
}

var opt int = 1

for {
time.Sleep(3 * time.Second)
switch opt {
case 1:
log.Println("Executing query")
_, err := db.Query("select name from users")
if err != nil {
panic(err)
}
opt++
case 2:
log.Println("Executing update")
_, err := db.Exec("update users set name = 'Charles' where id = 1")
if err != nil {
panic(err)
}
opt = 1
default:
panic("invalid option")
}
}
}()
app.Start()
}
20 changes: 20 additions & 0 deletions examples/promsql/driver_collector/services/prometheus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package services

import (
promsrv "github.com/lab259/go-rscsrv-prometheus"
)

var DefaultPromService PromService

type PromService struct {
promsrv.Service
}

// Name implements the rscsrv.Service interface.
func (srv *PromService) Name() string {
return "Prometheus Service"
}

func (service *PromService) Start() error {
return nil
}
42 changes: 42 additions & 0 deletions examples/promsql/driver_collector/services/psql_collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package services

import (
"github.com/lab259/go-rscsrv-prometheus/promsql"
_ "github.com/lib/pq"
)

var DefaultDriverCollector DriverCollectorService

type DriverCollectorService struct {
promsql.DriverCollector
}

// Name implements the rscsrv.Service interface.
func (srv *DriverCollectorService) Name() string {
return "Driver Collector Service"
}

func (service *DriverCollectorService) Start() error {
collector, err := promsql.Register(promsql.DriverCollectorOpts{
DriverName: "postgres",
})
if err != nil {
return err
}
service.DriverCollector = *collector

return DefaultPromService.Register(&service.DriverCollector)
}

// Restart restarts the Prometheus service.
func (service *DriverCollectorService) Restart() error {
if err := service.Stop(); err != nil {
return err
}
return service.Start()
}

// Stop stops the Prometheus service.
func (service *DriverCollectorService) Stop() error {
return nil
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/lab259/errors/v2 v2.2.0
github.com/lab259/go-rscsrv v0.2.1
github.com/lab259/hermes v1.1.0
github.com/lib/pq v1.3.0
github.com/onsi/ginkgo v1.8.0
github.com/onsi/gomega v1.5.0
github.com/prometheus/client_golang v1.0.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ github.com/lab259/rlog v2.0.1+incompatible h1:jgiVSY02jP/XAJxEfZpwuzkIYvmHKsmciF
github.com/lab259/rlog v2.0.1+incompatible/go.mod h1:6r9Y6mLv1FUvGwaBKL+6v0O+dIp6GNSzylJdYOEOIGA=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
Expand Down
12 changes: 4 additions & 8 deletions promsql/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package promsql_test
import (
"database/sql"
"testing"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -39,10 +38,9 @@ var _ = Describe("Database Collector", func() {
collector := promsql.NewDatabaseCollector(nil, promsql.DatabaseCollectorOpts{})
ch := make(chan *prometheus.Desc)
go func() {
time.Sleep(time.Second)
collector.Describe(ch)
close(ch)
}()
go collector.Describe(ch)

Expect((<-ch).String()).To(ContainSubstring("db_max_open_connections"))
Expect((<-ch).String()).To(ContainSubstring("db_pool_open_connections"))
Expand All @@ -60,10 +58,9 @@ var _ = Describe("Database Collector", func() {
})
ch := make(chan *prometheus.Desc)
go func() {
time.Sleep(time.Second)
collector.Describe(ch)
close(ch)
}()
go collector.Describe(ch)

Expect((<-ch).String()).To(ContainSubstring("db_test_max_open_connections"))
Expect((<-ch).String()).To(ContainSubstring("db_test_pool_open_connections"))
Expand All @@ -75,14 +72,13 @@ var _ = Describe("Database Collector", func() {
Expect((<-ch).String()).To(ContainSubstring("db_test_max_lifetime_closed"))
})

It("should generate default description names", func() {
It("should generate default metric values", func() {
collector := promsql.NewDatabaseCollector(&fakeDB{}, promsql.DatabaseCollectorOpts{})
ch := make(chan prometheus.Metric)
go func() {
time.Sleep(time.Second)
collector.Collect(ch)
close(ch)
}()
go collector.Collect(ch)

var metric dto.Metric
Expect((<-ch).Write(&metric)).To(Succeed())
Expand Down

0 comments on commit 6d0a676

Please sign in to comment.