diff options
| author | Shulhan <ms@kilabit.info> | 2019-01-04 07:53:02 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2019-01-04 13:14:43 +0700 |
| commit | 65e1848bd4aec12390fe15ebd83ff4bc53a8afec (patch) | |
| tree | a499ab074e8f347a8e7d14fccd1c94d783254f2d | |
| parent | 34ae901ff30a32d9aef33bfe25561ff2f685cb0c (diff) | |
| download | haminer-65e1848bd4aec12390fe15ebd83ff4bc53a8afec.tar.xz | |
config: replace configuration with ini file format
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | cmd/haminer/haminer.conf | 16 | ||||
| -rw-r--r-- | config.go | 122 | ||||
| -rw-r--r-- | config_test.go | 214 | ||||
| -rw-r--r-- | go.mod | 4 | ||||
| -rw-r--r-- | go.sum | 3 | ||||
| -rw-r--r-- | testdata/haminer.conf | 5 |
7 files changed, 303 insertions, 63 deletions
@@ -1 +1,3 @@ /haminer +/cover.out +/cover.html diff --git a/cmd/haminer/haminer.conf b/cmd/haminer/haminer.conf index 80bd2e0..8bdec74 100644 --- a/cmd/haminer/haminer.conf +++ b/cmd/haminer/haminer.conf @@ -1,7 +1,8 @@ +[haminer] ## ## Set default listen address in UDP. ## -## Format: <ADDR:PORT> +## Format: ADDR [ ":" PORT ] ## Default: 127.0.0.1:5140 ## ## Examples, @@ -15,11 +16,12 @@ ## List of HAProxy backend to be accepted and forwarded to Influxdb. Each ## backend name is separated by comma. ## -## Format: [name],... +## Format: [ name ] *[ "," name ] ## Default: "", no filter (all backend are accepted). ## ## Examples, -## accept_backend=api_01,api_02 +## +## accept_backend=api_01,api_02 ## #accept_backend= @@ -28,13 +30,13 @@ ## Parse HTTP request header in log file generated by "capture request header ## ..." option. ## -## Format: name | ... +## Format: [ name ] *["|" name] ## The name should contains only alphabets and underscore. ## Default: "" (empty) ## ## Examples, ## -## capture_request_header = host | referer +## capture_request_header = host | referrer ## #capture_request_header= @@ -47,8 +49,8 @@ ## Default: "", empty. If empty the log will not forwarded to Influxdb. ## ## Examples, -##influxdb_api_write=http://127.0.0.1:8086/write?db=haminer&u=haminer&p=haminer -##influxdb_api_write=http://192.168.56.10:8086/write?db=haminer&u=haminer&p=haminer&precision=ns +## +## influxdb_api_write=http://127.0.0.1:8086/write?db=haminer&u=haminer&p=haminer ## #influxdb_api_write= @@ -5,11 +5,11 @@ package haminer import ( - "bytes" - "io/ioutil" "log" "strconv" "strings" + + "github.com/shuLhan/share/lib/ini" ) // List of config keys. @@ -22,10 +22,9 @@ const ( // List of default config key values. const ( - DefListenAddr = "127.0.0.1" - DefListenPort = 5140 - DefInfluxAPIWrite = "http://127.0.0.1:8086/write?db=haproxy" - DefMaxBufferedLogs = 10 + defListenAddr = "127.0.0.1" + defListenPort = 5140 + defMaxBufferedLogs = 10 ) // @@ -53,89 +52,100 @@ type Config struct { } // -// NewConfig will create, initialize, and return new config with defautl +// NewConfig will create, initialize, and return new config with default // values. // func NewConfig() (cfg *Config) { return &Config{ - ListenAddr: DefListenAddr, - ListenPort: DefListenPort, - MaxBufferedLogs: DefMaxBufferedLogs, + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + } +} + +// +// Load configuration from file defined by `path`. +// +func (cfg *Config) Load(path string) { + if len(path) == 0 { + return + } + + in, err := ini.Open(path) + if err != nil { + log.Println(err) + return + } + + v, _ := in.Get("haminer", "", ConfigKeyListen) + cfg.SetListen(v) + + v, _ = in.Get("haminer", "", ConfigKeyAcceptBackend) + cfg.ParseAcceptBackend(v) + + v, _ = in.Get("haminer", "", ConfigKeyCaptureRequestHeader) + cfg.ParseCaptureRequestHeader(v) + + v, _ = in.Get("haminer", "", ConfigKeyInfluxAPIWrite) + if len(v) > 0 { + cfg.InfluxAPIWrite = v } } // -// SetListen will parse `v` value as "addr:port", and set config address and port -// based on it. +// SetListen will parse `v` value as "addr:port", and set config address and +// port based on it. // func (cfg *Config) SetListen(v string) { + if len(v) == 0 { + return + } + var err error addrPort := strings.Split(v, ":") switch len(addrPort) { - case 0: - return case 1: cfg.ListenAddr = addrPort[0] case 2: cfg.ListenAddr = addrPort[0] cfg.ListenPort, err = strconv.Atoi(addrPort[1]) if err != nil { - cfg.ListenPort = DefListenPort + cfg.ListenPort = defListenPort } } } -// -// parseCaptureRequestHeader Parse request header names where each name is -// separated by "|". -// -func (cfg *Config) parseCaptureRequestHeader(v []byte) { - sep := []byte{'|'} - headers := bytes.Split(v, sep) - for x := 0; x < len(headers); x++ { - headers[x] = bytes.TrimSpace(headers[x]) - cfg.RequestHeaders = append(cfg.RequestHeaders, string(headers[x])) +func (cfg *Config) ParseAcceptBackend(v string) { + v = strings.TrimSpace(v) + if len(v) == 0 { + return + } + + for _, v = range strings.Split(v, ",") { + if len(v) == 0 { + continue + } + cfg.AcceptBackend = append(cfg.AcceptBackend, strings.TrimSpace(v)) } } // -// Load will read configuration from file defined by `path`. +// ParseCaptureRequestHeader Parse request header names where each name is +// separated by "|". // -func (cfg *Config) Load(path string) { - bb, err := ioutil.ReadFile(path) - if err != nil { - log.Println(err) +func (cfg *Config) ParseCaptureRequestHeader(v string) { + v = strings.TrimSpace(v) + if len(v) == 0 { return } - lines := bytes.Split(bb, []byte("\n")) - - for _, line := range lines { - if len(line) == 0 { - continue - } - if line[0] == '#' { - continue - } - - kv := bytes.SplitN(line, []byte("="), 2) - if len(kv) != 2 { + headers := strings.Split(v, "|") + for x := 0; x < len(headers); x++ { + headers[x] = strings.TrimSpace(headers[x]) + if len(headers[x]) == 0 { continue } - - switch string(kv[0]) { - case ConfigKeyListen: - cfg.SetListen(string(kv[1])) - case ConfigKeyCaptureRequestHeader: - cfg.parseCaptureRequestHeader(kv[1]) - case ConfigKeyAcceptBackend: - v := string(bytes.TrimSpace(kv[1])) - if len(v) > 0 { - cfg.AcceptBackend = strings.Split(v, ",") - } - case ConfigKeyInfluxAPIWrite: - cfg.InfluxAPIWrite = string(kv[1]) - } + cfg.RequestHeaders = append(cfg.RequestHeaders, headers[x]) } } diff --git a/config_test.go b/config_test.go new file mode 100644 index 0000000..9f595b7 --- /dev/null +++ b/config_test.go @@ -0,0 +1,214 @@ +// Copyright 2019, M. Shulhan (ms@kilabit.info). All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package haminer + +import ( + "testing" + + "github.com/shuLhan/share/lib/test" +) + +func TestNewConfig(t *testing.T) { + cases := []struct { + desc string + exp *Config + }{{ + desc: "With default config", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + }, + }} + + for _, c := range cases { + t.Log(c.desc) + + got := NewConfig() + + test.Assert(t, "Config", c.exp, got, true) + } +} + +func TestLoad(t *testing.T) { + cases := []struct { + desc string + in string + exp *Config + }{{ + desc: "With empty path", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + }, + }, { + desc: "With path not exist", + in: "testdata/notexist.conf", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + }, + }, { + desc: "With path exist", + in: "testdata/haminer.conf", + exp: &Config{ + ListenAddr: "0.0.0.0", + ListenPort: 8080, + MaxBufferedLogs: defMaxBufferedLogs, + AcceptBackend: []string{ + "a", + "b", + }, + RequestHeaders: []string{ + "host", + "referrer", + }, + InfluxAPIWrite: "http://127.0.0.1:8086/write", + }, + }} + + for _, c := range cases { + t.Log(c.desc) + + got := NewConfig() + got.Load(c.in) + + test.Assert(t, "Config", c.exp, got, true) + } +} + +func TestSetListen(t *testing.T) { + cases := []struct { + desc string + in string + exp *Config + }{{ + desc: "With empty listen", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + }, + }, { + desc: "With empty port", + in: "127.0.0.2", + exp: &Config{ + ListenAddr: "127.0.0.2", + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + }, + }, { + desc: "With no port", + in: "127.0.0.3:", + exp: &Config{ + ListenAddr: "127.0.0.3", + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + }, + }} + + for _, c := range cases { + t.Log(c.desc) + + got := NewConfig() + got.SetListen(c.in) + + test.Assert(t, "Config", c.exp, got, true) + } +} + +func TestParseAcceptBackend(t *testing.T) { + cases := []struct { + desc string + in string + exp *Config + }{{ + desc: "With empty value", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + }, + }, { + desc: "With no separator", + in: "a ; b", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + AcceptBackend: []string{ + "a ; b", + }, + }, + }, { + desc: "With comma at beginning and end", + in: ",a,b,", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + AcceptBackend: []string{ + "a", "b", + }, + }, + }} + + for _, c := range cases { + t.Log(c.desc) + + got := NewConfig() + got.ParseAcceptBackend(c.in) + + test.Assert(t, "Config", c.exp, got, true) + } +} + +func TestParseCaptureRequestHeader(t *testing.T) { + cases := []struct { + desc string + in string + exp *Config + }{{ + desc: "With empty value", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + }, + }, { + desc: "With no separator", + in: "a ; b", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + RequestHeaders: []string{ + "a ; b", + }, + }, + }, { + desc: "With separator at beginning and end", + in: "|a|b|", + exp: &Config{ + ListenAddr: defListenAddr, + ListenPort: defListenPort, + MaxBufferedLogs: defMaxBufferedLogs, + RequestHeaders: []string{ + "a", "b", + }, + }, + }} + + for _, c := range cases { + t.Log(c.desc) + + got := NewConfig() + got.ParseCaptureRequestHeader(c.in) + + test.Assert(t, "Config", c.exp, got, true) + } +} @@ -1 +1,5 @@ module github.com/shuLhan/haminer + +go 1.12 + +require github.com/shuLhan/share v0.2.0 @@ -0,0 +1,3 @@ +github.com/shuLhan/share v0.2.0 h1:xm12WiZ0L9Yj5fNUgxKXfpxl4SJ9VuRdRwbQ5cACeik= +github.com/shuLhan/share v0.2.0/go.mod h1:SjjW0kmafz7R07V8GP8D9YvTj0jQ4A5LoLVYjC+920U= +golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/testdata/haminer.conf b/testdata/haminer.conf new file mode 100644 index 0000000..554b04e --- /dev/null +++ b/testdata/haminer.conf @@ -0,0 +1,5 @@ +[haminer] +listen = 0.0.0.0:8080 +accept_backend = a , b, +capture_request_header = host | referrer| +influxdb_api_write = http://127.0.0.1:8086/write |
