In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces the Golang configuration information processing framework Viper what is useful, the article introduces in great detail, has a certain reference value, interested friends must read it!
Viper
Project address: https://github.com/spf13/viper
This article is translated from the README.md file in the project.
There are many Go language projects that use the Viper framework, such as:
Hugo
EMC RexRay
Imgur's Incus
Nanobox/Nanopack
Docker Notary
BloomApi
Doctl
Clairctl
What is Viper?
Viper is a library that facilitates Go language applications to process configuration information. It can handle configurations in multiple formats. The features it supports:
Set default value
Read configuration data from JSON, TOML, YAML, HCL, and Java properties files
Can monitor changes to the configuration file and reread the configuration file
Read configuration data from environment variables
Read data from the remote configuration system and monitor them (such as etcd, Consul)
Read configuration from command parameters
Read from buffer
Call the function to set the configuration information
Why use Viper
When building modern applications, you don't have to worry about the configuration file format; you can focus on building great software.
Viper can do the following:
Load and parse configuration files in JSON, TOML, YAML, HCL, or Java properties format
You can set default values for various configuration items
You can specify configuration items on the command line to override configuration values
An alias system is provided to rename parameters without breaking existing code
You can easily tell the difference between the command line parameters or configuration files provided by the user and the default
The priority order in which Viper reads configuration information, from high to low, is as follows:
Explicitly call the Set function
Command line argument
Environment variable
Configuration file
Key/value storage system
Default value
The key of the configuration item for Viper is case-insensitive.
Set value set default value
Default values are not required and will take effect if configuration files, environment variables, remote configuration systems, command line arguments, and Set functions are not specified.
Example:
Viper.SetDefault ("ContentDir", "content") viper.SetDefault ("LayoutDir", "layouts") viper.SetDefault ("Taxonomies", map [string] string {"tag": "tags", "category": "categories"}) reads the configuration file
Viper supports JSON, TOML, YAML, HCL, and Java properties files.
Viper can search multiple paths, but currently a single Viper instance only supports a single profile.
Viper does not search any paths by default.
The following is an example of how to use Viper to search for and read configuration files.
The path is not required, but it is best to provide at least one path to find a configuration file.
Viper.SetConfigName ("config") / / set the profile name (without suffix) viper.AddConfigPath ("/ etc/appname/") / / the first search path viper.AddConfigPath ("$HOME/.appname") / / add the path viper.AddConfigPath (".") / / for example, add the current directory err: = viper.ReadInConfig () / / search path And read the configuration data if err! = nil {panic (fmt.Errorf ("Fatal error config file:% s\ n", err))} monitor the configuration file and re-read the configuration data
Viper support gives your application the ability to read configuration files at run time.
Gone are the days when you need to restart the server for the configuration to take effect, and viper-driven applications can read updated configuration files at run time without missing any beats.
You only need to call the WatchConfig function of the viper instance, or you can specify a callback function to be notified of the change.
Viper.WatchConfig () viper.OnConfigChange (func (e fsnotify.Event) {fmt.Println ("Config file changed:", e.Name)}) reads the configuration from io.Reader
Viper predefines many configuration sources, such as files, environment variables, command-line parameters, and remote K / V storage systems, but you are not constrained by them.
You can also implement your own configuration source and provide it to viper.
Viper.SetConfigType ("yaml") / / or viper.SetConfigType ("YAML") / / any approach to require this configuration into your program.var yamlExample = [] byte (`Hacker: truename: stevehobbies:- skateboarding- snowboarding- goclothing: jacket: leather trousers: denimage: 35eyes: brownbeard: true`) viper.ReadConfig (bytes.NewBuffer (yamlExample) viper.Get ("name") / / return "steve" Set calls viper.Set ("Verbose", true) viper.Set ("LogFile", LogFile) to register and use aliases
Aliases can implement multiple key references to a single value.
Viper.RegisterAlias ("loud", "Verbose") viper.Set ("verbose", true) viper.Set ("loud", true) / / these two sentences set the same value viper.GetBool ("loud") / / trueviper.GetBool ("verbose") / / true to read from the environment variable.
Viper fully supports environment variables, which can be used right out of the box.
There are four methods related to environment variables:
AutomaticEnv ()
BindEnv (string...): error
SetEnvPrefix (string)
SetEnvKeyReplacer (string...) * strings.Replacer
Note that environment variables are case-sensitive.
Viper provides a mechanism to ensure that Env variables are unique. With SetEnvPrefix, the set prefix is added when reading from the environment variable. Both BindEnv and AutomaticEnv use this prefix.
BindEnv requires one or two parameters. The first parameter is the key name, and the second parameter is the name of the environment variable. The name of the environment variable is case-sensitive. If no ENV variable name is provided, Viper automatically assumes that the key name matches the ENV variable name and that the ENV variable is all uppercase. When you explicitly provide an ENV variable name, it does not automatically add a prefix.
When using the ENV variable, note that when associated, the ENV value is read every time it is accessed. Viper does not read the ENV value when BindEnv is called.
The combination of AutomaticEnv and SetEnvPrefix will be particularly useful. When AutomaticEnv is called, any viper.Get request gets the environment variable. The name of the environment variable is the prefix set by SetEnvPrefix, plus the capitalization of the corresponding name.
SetEnvKeyReplacer allows you to use a strings.Replacer object to rewrite the configuration name to the Env name. You can use this method if you want to use the configuration name that contains-in Get (), but you want the corresponding environment variable name to contain the _ delimiter. An example of using it can be found in the viper_test.go file in the project.
Example:
SetEnvPrefix ("spf") / / will be automatically converted to uppercase BindEnv ("id") os.Setenv ("SPF_ID", "13") / / usually through the system environment variable to set id: = Get ("id") / / 13 bind command line parameter
Viper supports binding pflags parameters.
Like BindEnv, when a bound method is called, the value is not obtained, but is obtained when it is accessed. This means that binding should be done as soon as possible, even in the init () function.
You can bind a single flag using the BindPFlag () method.
Example:
ServerCmd.Flags () .Int ("port", 1138, "Port to run Application server on") viper.BindPFlag ("port", serverCmd.Flags () .Lookup ("port")
You can also bind an existing pflag collection (pflag.FlagSet):
Pflag.Int ("flagname", 1234, "help message for flagname") pflag.Parse () viper.BindPFlags (pflag.CommandLine) I: = viper.GetInt ("flagname") / / get the value from pflag through viper
Using pflag does not affect other libraries from using flag in the standard library. Through import, pflag can take over parameters defined through the flag of the standard library. This is done by calling the AddGoFlagSet () method in the pflag package.
Example:
Package mainimport ("flag"github.com/spf13/pflag") func main () {/ / using standard library "flag" package flag.Int ("flagname", 1234, "help message for flagname") pflag.CommandLine.AddGoFlagSet (flag.CommandLine) pflag.Parse () viper.BindPFlags (pflag.CommandLine) I: = viper.GetInt ("flagname") / / retrieve value from viper.} Flag interface
If you do not want to use pflag,Viper provides two interfaces to bind other flag systems.
Use the FlagValue interface to represent a single flag. The following is a simple example that implements this interface:
Type myFlag struct {} func (f myFlag) HasChanged () bool {return false} func (f myFlag) Name () string {return "my-flag-name"} func (f myFlag) ValueString () string {return "my-flag-value"} func (f myFlag) ValueType () string {return "string"}
Once you have implemented the interface, you can bind it:
Viper.BindFlagValue ("my-flag-name", myFlag {})
Use the FlagValueSet interface to represent a set of flag. The following is a simple example that implements this interface:
Type myFlagSet struct {flags [] myFlag} func (f myFlagSet) VisitAll (fn func (FlagValue)) {for _, flag: = range flags {fn (flag)}}
Once you have implemented the interface, you can bind it:
FSet: = myFlagSet {flags: [] myFlag {myFlag {}, myFlag {}},} viper.BindFlagValues ("my-flags", fSet) supports remote Key/Value storage
To enable this feature, you need to import the viper/remot package:
Import _ "github.com/spf13/viper/remote"
Viper can read a configuration string (in JSON, TOML, YAML, or HCL format) from a path to a remote Key/Value storage system such as etcd, Consul.
These values take precedence over the default values, but are overridden by configuration from disk files, command line flag, and environment variables.
Viper uses crypt to read the configuration from the Kramp V storage system, which means that you can encrypt and store your configuration information and automatically decrypt it. Encryption is optional.
You can use a remote configuration in conjunction with a local configuration, or you can use it independently.
Crypt has a command-line tool that can help you store configuration information to the K V storage system. Crypt uses etcd on http://127.0.0.1:4001 by default.
$go get github.com/xordataexchange/crypt/bin/crypt$ crypt set-plaintext / config/hugo.json / Users/hugo/settings/config.json
Make sure your value is set:
$crypt get-plaintext / config/hugo.json
See the documentation for examples of how crypt sets encryption values or how to use Consul.
Example of remote Key/Value storage-unencrypted viper.AddRemoteProvider ("etcd", "http://127.0.0.1:4001","/config/hugo.json")viper.SetConfigType("json") / because you don't know the format, you need to specify Supported formats are "json", "toml", "yaml", "yml", "properties", "props", "prop" err: = viper.ReadRemoteConfig () remote Key/Value storage example-encrypted viper.AddSecureRemoteProvider ("etcd", "http://127.0.0.1:4001","/config/hugo.json","/etc/secrets/mykeyring.gpg")viper.SetConfigType("json") / because the format is not known, so you need to specify Supported formats are "json", "toml", "yaml", "yml", "properties", "props", "prop" err: = viper.ReadRemoteConfig () Monitoring etcd changes-unencrypted / / you can create a new viper instance var runtime_viper = viper.New () runtime_viper.AddRemoteProvider ("etcd", "viper") "/ config/hugo.yml") runtime_viper.SetConfigType ("yaml") / / because the format is not known So you need to specify Supported formats are "json", "toml", "yaml", "yml", "properties", "props", "prop" / / read configuration err from remote: = runtime_viper.ReadRemoteConfig () / / parse configuration into runtime_conf runtime_viper.Unmarshal (& runtime_conf) / / change go func () {for {time.Sleep (time.Second * 5) / / delay after each request / / currently via a remote configuration of goroutine Only tested with etcd support err: = runtime_viper.WatchRemoteConfig () if err! = nil {log.Errorf ("unable to read remote config:% v", err) continue} / / parses the new configuration into a structure variable You can also use channel to implement a signal notification runtime_viper.Unmarshal (& runtime_conf)}} () to get the value
In Viper, there are ways to get a value based on the type of value. The following methods exist:
Get (key string): interface {}
GetBool (key string): bool
GetFloat64 (key string): float64
GetInt (key string): int
GetString (key string): string
GetStringMap (key string): map [string] interface {}
GetStringMapString (key string): map [string] string
GetStringSlice (key string): [] string
GetTime (key string): time.Time
GetDuration (key string): time.Duration
IsSet (key string): bool
If the Get function does not find a value, it returns a zero value of the corresponding type. You can use the IsSet () method to detect the existence of a key.
Example:
Viper.GetString ("logfile") / / Setting & Getting is not case-sensitive if viper.GetBool ("verbose") {fmt.Println ("verbose enabled")} access nested keys
The access method also accepts nested keys. For example, if the following JSON file is loaded:
{"host": {"address": "localhost", "port": 5799}, "datastore": {"metric": {"host": "127.0.0.1", "port": 3099}, "warehouse": {"host": "198.0.0.1" "port": 2112}}
Viper can pass. Delimiters to access nested fields:
GetString ("datastore.metric.host") / / (returns "127.0.0.1")
This follows the previously established priority rules; all configurations in the path are searched until they are found.
For example, the above files, datastore.metric.host and datastore.metric.port, have been defined (and may be overwritten). If there is another default value for datastore.metric.protocol, Viper will also find it.
However, if the datastore.metricvalue is overridden (through flags, environment variables, Set methods,...), then all datastore.metric subkeys will be undefined and will be "obscured" by higher priority configuration values.
Finally, if there is a matching nested key, its value is returned. For example:
{"datastore.metric.host": "0.0.0.0", "host": {"address": "localhost", "port": 5799}, "datastore": {"metric": {"host": "127.0.0.1", "port": 3099} "warehouse": {"host": "198.0.0.1", "port": 2112}} GetString ("datastore.metric.host") / / returns "0.0.0.0" extract subtree configuration
You can extract subtrees from viper. For example, viper is configured to:
App: cache1: max-items: 100 item-size: 64 cache2: max-items: 200 item-size: 80
After execution:
Subv: = viper.Sub ("app.cache1")
Subv represents:
Max-items: 100item-size: 64
Suppose we have the following function:
Func NewCache (cfg * Viper) * Cache {...}
Its function is to create a cache based on configuration information. It is now easy to create these two caches separately:
Cfg1: = viper.Sub ("app.cache1") cache1: = NewCache (cfg1) cfg2: = viper.Sub ("app.cache2") cache2: = NewCache (cfg2) parsing configuration
You can also choose to resolve all or specific values to struct, map, and so on.
There are two ways to do this:
Unmarshal (rawVal interface {}): error
UnmarshalKey (key string, rawVal interface {}): error
For example:
Type config struct {Port int Name string PathMap string `mapstructure: "path_map" `} var C configerr: = Unmarshal (& C) if err! = nil {t.Fatalf ("unable to decode into struct,% v", err)} use a single viper or multiple viper
Viper is ready to use right out of the box. Viper can be used without any configuration or initialization. Because most applications want to be configured with a single storage center, the viper package provides this feature. It is similar to a singleton pattern.
In all of the above examples, they demonstrate how to use the singleton style of viper.
Using multiple viper instances
You can also create many different viper instances for use by your applications. Each instance has its own independent settings and configuration values. Each instance can be read from a different configuration file, Kramp V storage system, etc. All functions supported by the viper package also have corresponding viper instance methods.
Example:
X: = viper.New () y: = viper.New () x.SetDefault ("ContentDir", "content") y.SetDefault ("ContentDir", "foobar") / /.
When using multiple viper instances, users need to manage each instance themselves.
The above is all the content of the article "what is the use of the configuration information processing framework Viper in Golang". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.