forked from elastic/beats
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
logp
package and its minor dependencies (elastic#6)
- Loading branch information
Showing
36 changed files
with
4,981 additions
and
7 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
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,290 @@ | ||
// Licensed to Elasticsearch B.V. under one or more contributor | ||
// license agreements. See the NOTICE file distributed with | ||
// this work for additional information regarding copyright | ||
// ownership. Elasticsearch B.V. licenses this file to you under | ||
// the Apache License, Version 2.0 (the "License"); you may | ||
// not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, | ||
// software distributed under the License is distributed on an | ||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
// KIND, either express or implied. See the License for the | ||
// specific language governing permissions and limitations | ||
// under the License. | ||
|
||
package config | ||
|
||
import ( | ||
"flag" | ||
"strings" | ||
|
||
ucfg "github.com/elastic/go-ucfg" | ||
cfgflag "github.com/elastic/go-ucfg/flag" | ||
) | ||
|
||
// StringsFlag collects multiple usages of the same flag into an array of strings. | ||
// Duplicate values will be ignored. | ||
type StringsFlag struct { | ||
list *[]string | ||
isDefault bool | ||
flag *flag.Flag | ||
} | ||
|
||
// SettingsFlag captures key/values pairs into an Config object. | ||
// The flag backed by SettingsFlag can be used multiple times. | ||
// Values are overwritten by the last usage of a key. | ||
type SettingsFlag cfgflag.FlagValue | ||
|
||
// flagOverwrite provides a flag value, which always overwrites the same setting | ||
// in an Config object. | ||
type flagOverwrite struct { | ||
config *ucfg.Config | ||
path string | ||
value string | ||
} | ||
|
||
// StringArrFlag creates and registers a new StringsFlag with the given FlagSet. | ||
// If no FlagSet is passed, flag.CommandLine will be used as target FlagSet. | ||
func StringArrFlag(fs *flag.FlagSet, name, def, usage string) *StringsFlag { | ||
var arr *[]string | ||
if def != "" { | ||
arr = &[]string{def} | ||
} else { | ||
arr = &[]string{} | ||
} | ||
|
||
return StringArrVarFlag(fs, arr, name, usage) | ||
} | ||
|
||
// StringArrVarFlag creates and registers a new StringsFlag with the given | ||
// FlagSet. Results of the flag usage will be appended to `arr`. If the slice | ||
// is not initially empty, its first value will be used as default. If the flag | ||
// is used, the slice will be emptied first. If no FlagSet is passed, | ||
// flag.CommandLine will be used as target FlagSet. | ||
func StringArrVarFlag(fs *flag.FlagSet, arr *[]string, name, usage string) *StringsFlag { | ||
if fs == nil { | ||
fs = flag.CommandLine | ||
} | ||
f := NewStringsFlag(arr) | ||
f.Register(fs, name, usage) | ||
return f | ||
} | ||
|
||
// NewStringsFlag creates a new, but unregistered StringsFlag instance. | ||
// Results of the flag usage will be appended to `arr`. If the slice is not | ||
// initially empty, its first value will be used as default. If the flag is | ||
// used, the slice will be emptied first. | ||
func NewStringsFlag(arr *[]string) *StringsFlag { | ||
if arr == nil { | ||
panic("No target array") | ||
} | ||
return &StringsFlag{list: arr, isDefault: true} | ||
} | ||
|
||
// Register registers the StringsFlag instance with a FlagSet. | ||
// A valid FlagSet must be used. | ||
// Register panics if the flag is already registered. | ||
func (f *StringsFlag) Register(fs *flag.FlagSet, name, usage string) { | ||
if f.flag != nil { | ||
panic("StringsFlag is already registered") | ||
} | ||
|
||
fs.Var(f, name, usage) | ||
f.flag = fs.Lookup(name) | ||
if f.flag == nil { | ||
panic("Failed to lookup registered flag") | ||
} | ||
|
||
if len(*f.list) > 0 { | ||
f.flag.DefValue = (*f.list)[0] | ||
} | ||
} | ||
|
||
// String joins all it's values set into a comma-separated string. | ||
func (f *StringsFlag) String() string { | ||
if f == nil || f.list == nil { | ||
return "" | ||
} | ||
|
||
l := *f.list | ||
return strings.Join(l, ", ") | ||
} | ||
|
||
// SetDefault sets the flags new default value. | ||
// This overwrites the contents in the backing array. | ||
func (f *StringsFlag) SetDefault(v string) { | ||
if f.flag != nil { | ||
f.flag.DefValue = v | ||
} | ||
|
||
*f.list = []string{v} | ||
f.isDefault = true | ||
} | ||
|
||
// Set is used to pass usage of the flag to StringsFlag. Set adds the new value | ||
// to the backing array. The array will be emptied on Set, if the backing array | ||
// still contains the default value. | ||
func (f *StringsFlag) Set(v string) error { | ||
// Ignore duplicates, can be caused by multiple flag parses | ||
if f.isDefault { | ||
*f.list = []string{v} | ||
} else { | ||
for _, old := range *f.list { | ||
if old == v { | ||
return nil | ||
} | ||
} | ||
*f.list = append(*f.list, v) | ||
} | ||
f.isDefault = false | ||
return nil | ||
} | ||
|
||
// Get returns the backing slice its contents as interface{}. The type used is | ||
// `[]string`. | ||
func (f *StringsFlag) Get() interface{} { | ||
return f.List() | ||
} | ||
|
||
// List returns the current set values. | ||
func (f *StringsFlag) List() []string { | ||
return *f.list | ||
} | ||
|
||
// Type reports the type of contents (string) expected to be parsed by Set. | ||
// It is used to build the CLI usage string. | ||
func (f *StringsFlag) Type() string { | ||
return "string" | ||
} | ||
|
||
// SettingFlag defines a setting flag, name and it's usage. The return value is | ||
// the Config object settings are applied to. | ||
func SettingFlag(fs *flag.FlagSet, name, usage string) *C { | ||
cfg := NewConfig() | ||
SettingVarFlag(fs, cfg, name, usage) | ||
return cfg | ||
} | ||
|
||
// SettingVarFlag defines a setting flag, name and it's usage. | ||
// Settings are applied to the Config object passed. | ||
func SettingVarFlag(fs *flag.FlagSet, def *C, name, usage string) { | ||
if fs == nil { | ||
fs = flag.CommandLine | ||
} | ||
|
||
f := NewSettingsFlag(def) | ||
fs.Var(f, name, usage) | ||
} | ||
|
||
// NewSettingsFlag creates a new SettingsFlag instance, not registered with any | ||
// FlagSet. | ||
func NewSettingsFlag(def *C) *SettingsFlag { | ||
opts := append( | ||
[]ucfg.Option{ | ||
ucfg.MetaData(ucfg.Meta{Source: "command line flag"}), | ||
}, | ||
configOpts..., | ||
) | ||
|
||
tmp := cfgflag.NewFlagKeyValue(def.access(), true, opts...) | ||
return (*SettingsFlag)(tmp) | ||
} | ||
|
||
func (f *SettingsFlag) access() *cfgflag.FlagValue { | ||
return (*cfgflag.FlagValue)(f) | ||
} | ||
|
||
// Config returns the config object the SettingsFlag stores applied settings to. | ||
func (f *SettingsFlag) Config() *C { | ||
return fromConfig(f.access().Config()) | ||
} | ||
|
||
// Set sets a settings value in the Config object. The input string must be a | ||
// key-value pair like `key=value`. If the value is missing, the value is set | ||
// to the boolean value `true`. | ||
func (f *SettingsFlag) Set(s string) error { | ||
return f.access().Set(s) | ||
} | ||
|
||
// Get returns the Config object used to store values. | ||
func (f *SettingsFlag) Get() interface{} { | ||
return f.Config() | ||
} | ||
|
||
// String always returns an empty string. It is required to fulfil | ||
// the flag.Value interface. | ||
func (f *SettingsFlag) String() string { | ||
return "" | ||
} | ||
|
||
// Type reports the type of contents (setting=value) expected to be parsed by Set. | ||
// It is used to build the CLI usage string. | ||
func (f *SettingsFlag) Type() string { | ||
return "setting=value" | ||
} | ||
|
||
// ConfigOverwriteFlag defines a new flag updating a setting in an Config | ||
// object. The name is used as the flag its name the path parameter is the | ||
// full setting name to be used when the flag is set. | ||
func ConfigOverwriteFlag( | ||
fs *flag.FlagSet, | ||
config *C, | ||
name, path, def, usage string, | ||
) *string { | ||
if config == nil { | ||
panic("Missing configuration") | ||
} | ||
if path == "" { | ||
panic("empty path") | ||
} | ||
|
||
if fs == nil { | ||
fs = flag.CommandLine | ||
} | ||
|
||
if def != "" { | ||
err := config.SetString(path, -1, def) | ||
if err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
f := newOverwriteFlag(config, path, def) | ||
fs.Var(f, name, usage) | ||
return &f.value | ||
} | ||
|
||
func newOverwriteFlag(c *C, path, def string) *flagOverwrite { | ||
return &flagOverwrite{config: c.access(), path: path, value: def} | ||
} | ||
|
||
func (f *flagOverwrite) String() string { | ||
return f.value | ||
} | ||
|
||
func (f *flagOverwrite) Set(v string) error { | ||
opts := append( | ||
[]ucfg.Option{ | ||
ucfg.MetaData(ucfg.Meta{Source: "command line flag"}), | ||
}, | ||
configOpts..., | ||
) | ||
|
||
err := f.config.SetString(f.path, -1, v, opts...) | ||
if err != nil { | ||
return err | ||
} | ||
f.value = v | ||
return nil | ||
} | ||
|
||
func (f *flagOverwrite) Get() interface{} { | ||
return f.value | ||
} | ||
|
||
func (f *flagOverwrite) Type() string { | ||
return "string" | ||
} |
Oops, something went wrong.