Skip to content

Commit

Permalink
Version 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrodejesus committed May 20, 2022
0 parents commit 7f1ab2b
Show file tree
Hide file tree
Showing 9 changed files with 2,037 additions and 0 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Gatekeeper Log Exporter

Gatekeeper Log Exporter (GKLE for shorten) provides an easy way to aggregate and export logs from <a href="https://github.com/AltraMayor/gatekeeper" target="_blank">Gatekeeper</a>.

## How it Works

GKLE works by listening to the Gatekeeper log directory and processing a complete log file every time a new one is generated.

While processing the log file, GKLE agreggates the lcore separated data and exports it (currently it only supports InfluxDB).

## How to Set Up

### Config file

A config file should be located at `/etc/gkle.yaml`. GKLE uses it to read the Gatekeeper log directory and get InfluxDB credentials.

The config file uses the following format:

```
gk_log_dir: ""
influxdb:
url: ""
user: ""
password: ""
database: ""
retention_policy: ""
log_level : 0
hostname: ""
```

`gk_log_dir` option receives the directory where gatekeeper is logging data (usually `/var/log/gatekeeper/`).

`influxdb` option receives: connection URL, username and password, the desired database and retention policy, the log level (0 to 3, as described <a href="https://pkg.go.dev/github.com/influxdata/influxdb-client-go#Options.SetLogLevel" target="_blank">here</a>), and finally the hostname of the server where Gatekeeper is running.

### Running

GKLE should be compiled and executed from systemd or another init system, so it can run on background listening to the files being created on the log directory.
44 changes: 44 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

import (
"fmt"
"os"

"github.com/hostnetbr/gatekeeper-log-exporter/exporter/influx"
yaml "gopkg.in/yaml.v2"
)

type Config struct {
GkLogDir string `yaml:"gk_log_dir"`
InfluxDB *influx.Config `yaml:"influxdb"`
}

func parseConfig() (Config, error) {
data, err := os.ReadFile(confFile)
if err != nil {
return Config{}, fmt.Errorf("error reading config file: %w", err)
}

var cfg Config
if err = yaml.Unmarshal(data, &cfg); err != nil {
return Config{}, fmt.Errorf("error parsing config: %w", err)
}

if cfg.GkLogDir == "" {
return Config{}, fmt.Errorf("gk_log_dir empty: %w", err)
}

if cfg.InfluxDB == nil {
return Config{}, fmt.Errorf("error parsing influxdb config")
}
if cfg.InfluxDB.User == "" || cfg.InfluxDB.Pass == "" || cfg.InfluxDB.Database == "" {
return Config{}, fmt.Errorf("not enough authentication credentials for influxdb")
}
if cfg.InfluxDB.Hostname == "" {
if cfg.InfluxDB.Hostname, err = os.Hostname(); err != nil {
return Config{}, fmt.Errorf("error parsing hostname: %w", err)
}
}

return cfg, nil
}
10 changes: 10 additions & 0 deletions etc/gkle.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
gk_log_dir: ""

influxdb:
url: ""
user: ""
password: ""
database: ""
retention_policy: ""
log_level: 0
hostname: ""
31 changes: 31 additions & 0 deletions exporter/exporter .go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package exporter

import (
"time"
)

type Measurements struct {
TotPktsNum uint64
TotPktsSize uint64
PktsNumGranted uint64
PktsSizeGranted uint64
PktsNumRequest uint64
PktsSizeRequest uint64
PktsNumDeclined uint64
PktsSizeDeclined uint64
TotPktsNumDropped uint64
TotPktsSizeDropped uint64
TotPktsNumDistributed uint64
TotPktsSizeDistributed uint64
}

type Entry struct {
Time time.Time
Lcore int
Measurements Measurements
}

type Interface interface {
Export(t time.Time, m *Measurements) error
Close()
}
75 changes: 75 additions & 0 deletions exporter/influx/influx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package influx

import (
"context"
"fmt"
"time"

"github.com/hostnetbr/gatekeeper-log-exporter/exporter"
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
)

type Config struct {
URL string `yaml:"url"`
User string `yaml:"user"`
Pass string `yaml:"password"`
Database string `yaml:"database"`
RetentionPolicy string `yaml:"retention_policy"`
LogLevel uint `yaml:"log_level"`
Hostname string `yaml:"hostname"`
}

type Exporter struct {
client influxdb2.Client
config Config
}

func NewExporter(config Config) Exporter {
options := influxdb2.DefaultOptions()
options.SetLogLevel(config.LogLevel)
client := influxdb2.NewClientWithOptions(config.URL, fmt.Sprintf("%s:%s", config.User, config.Pass), options)
return Exporter{client, config}
}

func (e Exporter) Export(t time.Time, m *exporter.Measurements) error {
measurements := measurementsToMap(m)
p := influxdb2.NewPoint(
"gkle",
map[string]string{"host": e.config.Hostname},
measurements,
t,
)

writeAPI := e.client.WriteAPIBlocking("", fmt.Sprintf("%s/%s", e.config.Database, e.config.RetentionPolicy))
err := writeAPI.WritePoint(context.Background(), p)
if err != nil {
return fmt.Errorf("error writing to influxdb: %w\n", err)
}

return nil
}

func (e Exporter) Close() {
e.client.Close()
}

func measurementsToMap(ms *exporter.Measurements) map[string]interface{} {
m := make(map[string]interface{})

// Parsing as int64 because InfluxDB seems to not support uint64.
// https://github.com/influxdata/influxdb/issues/9961
m["tot_pkts_num"] = int64(ms.TotPktsNum)
m["tot_pkts_size"] = int64(ms.TotPktsSize)
m["pkts_num_granted"] = int64(ms.PktsNumGranted)
m["pkts_size_granted"] = int64(ms.PktsSizeGranted)
m["pkts_num_request"] = int64(ms.PktsNumRequest)
m["pkts_size_request"] = int64(ms.PktsSizeRequest)
m["pkts_num_declined"] = int64(ms.PktsNumDeclined)
m["pkts_size_declined"] = int64(ms.PktsSizeDeclined)
m["tot_pkts_num_dropped"] = int64(ms.TotPktsNumDropped)
m["tot_pkts_size_dropped"] = int64(ms.TotPktsSizeDropped)
m["tot_pkts_num_distributed"] = int64(ms.TotPktsNumDistributed)
m["tot_pkts_size_distributed"] = int64(ms.TotPktsSizeDistributed)

return m
}
Loading

0 comments on commit 7f1ab2b

Please sign in to comment.