haminer

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2022 License: GPL-3.0 Imports: 15 Imported by: 0

README

// SPDX-FileCopyrightText: 2018 M. Shulhan <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
= haminer
:toc:
:sectanchors:
:sectlinks:

Library and program to parse and forward HAProxy logs.

Supported forwarder: Influxdb, QuestDB.


==  Installation

===  Building from source

*Requirements*

* https://golang.org[Go^] for building from source code
* https://git-scm.com/[git^] for downloading source code

Get the source code using git,

----
$ git clone https://git.sr.ht/~shulhan/haminer
$ cd haminer
$ make
----

The binary name is `haminer` build in the current directory.


===  Pre-build package

The Arch Linux package is available at build.kilabit.info.
Add the following repository to your pacman.conf,

----
[build.kilabit.info]
Server = https://build.kilabit.info/aur
----

To install it,

	$ sudo pacman -Sy --noconfirm haminer-git


== Configuration

haminer by default will load it's config from `/etc/haminer.conf`, if not
specified when running the program.

See
https://git.sr.ht/~shulhan/haminer/tree/main/item/cmd/haminer/haminer.conf[haminer.conf^]
for an example of possible configuration and their explanation.


===  Forwarders

Currently, there are two supported database where haminer can forward the
parsed log: influxdb and questdb.
Haminer support Influxdb v1 and v2.

====  Influxdb v1

For v1, you need to create the user and database first,

----
$ influx
> CREATE USER "haminer" WITH PASSWORD 'haminer'
> CREATE DATABASE haminer
> GRANT ALL ON haminer TO haminer
----

Example of forwarder configuration,

----
[forwarder "influxd"]
version = v1
url = http://127.0.0.1:8086
bucket = haminer
user = haminer
password  = haminer
----

====  Influxdb v2

For v2,

----
$ sudo influx bucket create \
	--name haminer \
	--retention 30d
----

For v2, the example configuration is

----
[forwarder "influxd"]
version = v1
url = http://127.0.0.1:8086
org = $org
bucket = haminer
token = $token
----

====  Questdb

For questdb the configuration is quite simple,

----
[forwarder "questdb"]
url = udp://127.0.0.1:9009
----

We did not need to create the table, questdb will handled that automatically.


==  Deployment

. Copy configuration from `$SOURCE/cmd/haminer/haminer/conf` to
`/etc/haminer.conf`

. Update haminer configuration in `/etc/haminer.conf`
+
--
For example,
----
[haminer]
listen = 127.0.0.1:5140

...
----

Add one or more provider to the configuration as the example above.
--

. Update HAProxy config to forward log to UDP port other than rsyslog.
+
--
For example,
----
global
	...
	log 127.0.0.1:5140 local3
	...
----
Then reload or restart HAProxy.
--

. Run the haminer program,
+
--
----
$ haminer
----
or use a
https://git.sr.ht/~shulhan/haminer/tree/main/item/cmd/haminer/haminer.service[systemd
service^].

----
$ sudo systemctl enable haminer
$ sudo systemctl start  haminer
----
--


==  License

----
haminer - Library and program to parse and forward HAProxy logs.
Copyright (C) 2018-2022 M. Shulhan <ms@kilabit.info>

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
details.

You should have received a copy of the GNU General Public License along with
this program.
If not, see <http://www.gnu.org/licenses/>.
----

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Forwarders map[string]*ConfigForwarder `ini:"forwarder"`

	// Listen is the address where Haminer will bind and receiving
	// log from HAProxy.
	Listen string `ini:"haminer::listen"`

	// AcceptBackend list of backend to be filtered.
	AcceptBackend []string `ini:"haminer::accept_backend"`

	// List of request headers to be parsed and mapped as tags in halog
	// output.
	RequestHeaders []string `ini:"haminer::capture_request_header"`

	HttpUrl []string `ini:"preprocess:tag:http_url"`

	// ForwardInterval define an interval where logs will be forwarded.
	ForwardInterval time.Duration `ini:"haminer::forward_interval"`
	// contains filtered or unexported fields
}

Config define options to create and run Haminer instance.

func NewConfig

func NewConfig() (cfg *Config)

NewConfig will create, initialize, and return new config with default values.

func (*Config) Load

func (cfg *Config) Load(path string) (err error)

Load configuration from file defined by `path`.

func (*Config) SetListen

func (cfg *Config) SetListen(v string)

SetListen will parse `v` value as "addr:port", and set config address and port based on it.

type ConfigForwarder

type ConfigForwarder struct {
	Version string `ini:"::version"`

	Url string `ini:"::url"`

	Bucket string `ini:"::bucket"`

	User string `ini:"::user"`
	Pass string `ini:"::pass"`

	Org   string `ini:"::org"`
	Token string `ini:"::token"`
	// contains filtered or unexported fields
}

ConfigForwarder contains configuration for forwarding the logs.

type Forwarder

type Forwarder interface {
	Forwards(halogs []*HttpLog)
}

Forwarder define an interface to forward parsed HAProxy log to storage engine.

type Haminer

type Haminer struct {
	// contains filtered or unexported fields
}

Haminer define the log consumer and producer.

func NewHaminer

func NewHaminer(cfg *Config) (h *Haminer)

NewHaminer create, initialize, and return new Haminer instance. If config parameter is nil, it will use the default options.

func (*Haminer) Start

func (h *Haminer) Start() (err error)

Start will listen for UDP packet and start consuming log, parse, and publish it to analytic server.

func (*Haminer) Stop

func (h *Haminer) Stop()

Stop will close UDP server and clear all resources.

type HttpLog

type HttpLog struct {
	Timestamp time.Time

	ClientIP   string
	ClientPort int32

	FrontendName string
	BackendName  string
	ServerName   string

	TimeReq     int32
	TimeWait    int32
	TimeConnect int32
	TimeRsp     int32
	TimeAll     int32

	BytesRead int64

	CookieReq string
	CookieRsp string

	TermState string

	ConnActive   int32
	ConnFrontend int32
	ConnBackend  int32
	ConnServer   int32
	ConnRetries  int32

	QueueServer  int32
	QueueBackend int32

	RequestHeaders map[string]string

	HTTPStatus int32
	HTTPMethod string
	HTTPURL    string
	HTTPQuery  string
	HTTPProto  string
	// contains filtered or unexported fields
}

HttpLog contains the mapping of haproxy HTTP log format to Go struct.

Reference: https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#8.2.3

func (*HttpLog) Parse

func (halog *HttpLog) Parse(in []byte, reqHeaders []string) (ok bool)

Parse will parse one line of HAProxy log format into HttpLog.

nolint: gocyclo

func (*HttpLog) ParseUDPPacket

func (halog *HttpLog) ParseUDPPacket(packet []byte, reqHeaders []string) bool

ParseUDPPacket will convert UDP packet (in bytes) to instance of HttpLog.

It will return nil and false if UDP packet is nil, have zero length, or cannot be parsed (rejected).

type InfluxdClient

type InfluxdClient struct {
	// contains filtered or unexported fields
}

InfluxdClient contains HTTP connection for writing logs to Influxd.

func NewInfluxdClient

func NewInfluxdClient(cfg *ConfigForwarder) (cl *InfluxdClient)

NewInfluxdClient will create, initialize, and return new Influxd client.

func (*InfluxdClient) Forwards

func (cl *InfluxdClient) Forwards(halogs []*HttpLog)

Forwards implement the Forwarder interface. It will write all logs to Influxd.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL