-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7f1ab2b
Showing
9 changed files
with
2,037 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
Oops, something went wrong.