Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandre committed Jul 29, 2019
1 parent aa92321 commit e14c64b
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
vendor
31 changes: 31 additions & 0 deletions Dockerfile
@@ -0,0 +1,31 @@
FROM golang:1.12.7-buster

# Set the Current Working Directory inside the container
WORKDIR $GOPATH/src/mautic_exporter

# Copy sources.
COPY . .

# Download all the dependencies.
RUN go get -d -v ./...

# Install the package
RUN go install -v ./...

ENV MAUTIC_DB_HOST="" \
MAUTIC_DB_PORT="3306" \
MAUTIC_DB_USER="" \
MAUTIC_DB_PASSWORD="" \
MAUTIC_DB_NAME="" \
MAUTIC_DB_TABLE_PREFIX=""

EXPOSE 9117

ADD /docker-entrypoint.sh /docker-entrypoint.sh

RUN set -x \
&& chmod +x /docker-entrypoint.sh

ENTRYPOINT ["/docker-entrypoint.sh"]

CMD ["mautic_exporter"]
124 changes: 124 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions Gopkg.toml
@@ -0,0 +1,11 @@
[[constraint]]
name = "github.com/Sirupsen/logrus"
version = "1.4.2"

[[constraint]]
name = "github.com/prometheus/client_golang"
version = "1.0.0"

[prune]
go-tests = true
unused-packages = true
2 changes: 1 addition & 1 deletion LICENSE
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Alexandre
Copyright (c) 2019 Alexandre L.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion README.md
@@ -1,2 +1,2 @@
# mautic_exporter
# Mautic Exporter
Prometheus exporter for Mautic
8 changes: 8 additions & 0 deletions docker-entrypoint.sh
@@ -0,0 +1,8 @@
#!/bin/bash
set -e

if [[ -n "${MAUTIC_DB_HOST}" ]]; then
exec "$@" -host="${MAUTIC_DB_HOST}" -port="${MAUTIC_DB_PORT}" -user="${MAUTIC_DB_USER}" -db="${MAUTIC_DB_NAME}" -tableprefix="${MAUTIC_DB_TABLE_PREFIX}" -pass="${MAUTIC_DB_PASSWORD}"
else
exec "$@"
fi
192 changes: 192 additions & 0 deletions mautic_exporter.go
@@ -0,0 +1,192 @@
package main

import (
"net/http"

log "github.com/Sirupsen/logrus"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"

"flag"
"fmt"
"os"

"database/sql"

_ "github.com/go-sql-driver/mysql"
)

//This is my collector metrics
type mauticCollector struct {
numLeadsMetric *prometheus.Desc
numEmailsMetric *prometheus.Desc
numCampaignsMetric *prometheus.Desc
numPageHitsMetric *prometheus.Desc
numWebhookQueueMetric *prometheus.Desc
numMessageQueueMetric *prometheus.Desc

dbHost string
dbName string
dbUser string
dbPass string
dbTablePrefix string
}

//This is a constructor for my mauticCollector struct
func newMauticCollector(host string, dbname string, username string, pass string, tablePrefix string) *mauticCollector {
return &mauticCollector{
numLeadsMetric: prometheus.NewDesc("mautic_numLeads_metric",
"Shows the number of leads in Mautic",
nil, nil,
),
numEmailsMetric: prometheus.NewDesc("mautic_numEmails_metric",
"Shows the number of emails in Mautic",
nil, nil,
),
numCampaignsMetric: prometheus.NewDesc("mautic_numCampaigns_metric",
"Shows the number of campaigns in Mautic",
nil, nil,
),
numPageHitsMetric: prometheus.NewDesc("mautic_numPageHits_metric",
"Shows the number of page hits in Mautic",
nil, nil,
),
numWebhookQueueMetric: prometheus.NewDesc("mautic_numWebhookQueue_metric",
"Shows the number of webhook in Mautic's queue",
nil, nil,
),
numMessageQueueMetric: prometheus.NewDesc("mautic_numMessageQueue_metric",
"Shows the number of message in Mautic's queue",
nil, nil,
),

dbHost: host,
dbName: dbname,
dbUser: username,
dbPass: pass,
dbTablePrefix: tablePrefix,
}
}

//Describe method is required for a prometheus.Collector type
func (collector *mauticCollector) Describe(ch chan<- *prometheus.Desc) {

//We set the metrics
ch <- collector.numLeadsMetric
ch <- collector.numEmailsMetric
ch <- collector.numCampaignsMetric
ch <- collector.numPageHitsMetric
ch <- collector.numWebhookQueueMetric
ch <- collector.numMessageQueueMetric

}

//Collect method is required for a prometheus.Collector type
func (collector *mauticCollector) Collect(ch chan<- prometheus.Metric) {

//We run DB queries here to retrieve the metrics we care about
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s", collector.dbUser, collector.dbPass, collector.dbHost, collector.dbName)

db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Fprintf(os.Stderr, "Error connecting to database: %s ...\n", err)
os.Exit(1)
}
defer db.Close()

//select count(*) as numLeads from leads;
var numLeads float64
q1 := fmt.Sprintf("select count(*) as numLeads from %sleads;", collector.dbTablePrefix)
err = db.QueryRow(q1).Scan(&numLeads)
if err != nil {
log.Fatal(err)
}

//select count(*) as numEmails from emails;
var numEmails float64
q2 := fmt.Sprintf("select count(*) as numEmails from %semails;", collector.dbTablePrefix)
err = db.QueryRow(q2).Scan(&numEmails)
if err != nil {
log.Fatal(err)
}

//select count(*) as numCampaigns from campaigns;
var numCampaigns float64
q3 := fmt.Sprintf("select count(*) as numCampaigns from %scampaigns;", collector.dbTablePrefix)
err = db.QueryRow(q3).Scan(&numCampaigns)
if err != nil {
log.Fatal(err)
}

//select count(*) as numPageHits from page_hits;
var numPageHits float64
q4 := fmt.Sprintf("select count(*) as numPageHits from %spage_hits;", collector.dbTablePrefix)
err = db.QueryRow(q4).Scan(&numPageHits)
if err != nil {
log.Fatal(err)
}

//select count(*) as numWebhookQueue from webhook_queue;
var numWebhookQueue float64
q5 := fmt.Sprintf("select count(*) as numWebhookQueue from %swebhook_queue;", collector.dbTablePrefix)
err = db.QueryRow(q5).Scan(&numWebhookQueue)
if err != nil {
log.Fatal(err)
}

//select count(*) as numMessageQueue from message_queue;
var numMessageQueue float64
q6 := fmt.Sprintf("select count(*) as numMessageQueue from %smessage_queue;", collector.dbTablePrefix)
err = db.QueryRow(q6).Scan(&numMessageQueue)
if err != nil {
log.Fatal(err)
}

//Write latest value for each metric in the prometheus metric channel.
//Note that you can pass CounterValue, GaugeValue, or UntypedValue types here.
ch <- prometheus.MustNewConstMetric(collector.numLeadsMetric, prometheus.CounterValue, numLeads)
ch <- prometheus.MustNewConstMetric(collector.numEmailsMetric, prometheus.CounterValue, numEmails)
ch <- prometheus.MustNewConstMetric(collector.numCampaignsMetric, prometheus.CounterValue, numCampaigns)
ch <- prometheus.MustNewConstMetric(collector.numPageHitsMetric, prometheus.CounterValue, numPageHits)
ch <- prometheus.MustNewConstMetric(collector.numWebhookQueueMetric, prometheus.CounterValue, numWebhookQueue)
ch <- prometheus.MustNewConstMetric(collector.numMessageQueueMetric, prometheus.CounterValue, numMessageQueue)

}

func main() {

mtHostPtr := flag.String("host", "127.0.0.1", "Hostname or Address for DB server")
mtPortPtr := flag.String("port", "3306", "DB server port")
mtNamePtr := flag.String("db", "", "DB name")
mtUserPtr := flag.String("user", "", "DB user for connection")
mtPassPtr := flag.String("pass", "", "DB password for connection")
mtTablePrefixPtr := flag.String("tableprefix", "", "Table prefix for Mautic tables")

flag.Parse()

dbHost := fmt.Sprintf("%s:%s", *mtHostPtr, *mtPortPtr)
dbName := *mtNamePtr
dbUser := *mtUserPtr
dbPassword := *mtPassPtr
tablePrefix := *mtTablePrefixPtr

if dbName == "" {
fmt.Fprintf(os.Stderr, "flag -db=dbname required!\n")
os.Exit(1)
}

if dbUser == "" {
fmt.Fprintf(os.Stderr, "flag -user=username required!\n")
os.Exit(1)
}

//We create the collector
collector := newMauticCollector(dbHost, dbName, dbUser, dbPassword, tablePrefix)
prometheus.MustRegister(collector)

//This section will start the HTTP server and expose
//any metrics on the /metrics endpoint.
http.Handle("/metrics", promhttp.Handler())
log.Info("Beginning to serve on port :9117")
log.Fatal(http.ListenAndServe(":9117", nil))
}

0 comments on commit e14c64b

Please sign in to comment.