Skip to content
/ konfig Public
forked from versus/konfig

A Minimal Unopinionated Library For Reading Configurations in Go

License

Notifications You must be signed in to change notification settings

isgasho/konfig

 
 

Repository files navigation

Go Doc Build Status Go Report Card Test Coverage Maintainability

konfig

This is a very minimal and unopinionated utility for reading configuration values in Go applications based on The 12-Factor App.

The idea is that you just define a struct with fields, types, and defaults, then you just use this library to read and populate the values for fields of your struct from either command-line flags, environment variables, or configuration files. It can also watch for new values read from configuration files and notify subscribers.

This library does not use flag package for parsing flags, so you can still parse your flags separately.

Quick Start

package main

import (
  "fmt"
  "net/url"
  "time"

  "github.com/moorara/konfig"
)

var config = struct {
  Enabled   bool
  LogLevel  string
  Timeout   time.Duration
  Address   url.URL
  Endpoints []string
} {
  Enabled:  true,   // default
  LogLevel: "info", // default
}

func main() {
  konfig.Pick(&config)
  fmt.Printf("%+v\n", config)
}

Examples & Demos

You can find examples of using konfig alongside some demos here.

Documentation

The precedence of sources for reading values is as follows:

  1. command-line flags
  2. environment variables
  3. configuration files
  4. default values (set when creating the instance)

You can pass the configuration values with flags using any of the syntaxes below:

main  -enabled  -log.level info  -timeout 30s  -address http://localhost:8080  -endpoints url1,url2,url3
main  -enabled  -log.level=info  -timeout=30s  -address=http://localhost:8080  -endpoints=url1,url2,url3
main --enabled --log.level info --timeout 30s --address http://localhost:8080 --endpoints url1,url2,url3
main --enabled --log.level=info --timeout=30s --address=http://localhost:8080 --endpoints=url1,url2,url3

You can pass the configuration values using environment variables as follows:

export ENABLED=true
export LOG_LEVEL=info
export TIMEOUT=30s
export ADDRESS=http://localhost:8080
export ENDPOINTS=url1,url2,url3

You can also write the configuration values in files (or mount your configuration values and secrets as files) and pass the paths to the files using environment variables:

export ENABLED_FILE=...
export LOG_LEVEL_FILE=...
export TIMEOUT_FILE=...
export ADDRESS_FILE=...
export ENDPOINTS_FILE=...

Supported Types

  • string, *string, []string
  • bool, *bool, []bool
  • float32, float64
  • *float32, *float64
  • []float32, []float64
  • int, int8, int16, int32, int64
  • *int, *int8, *int16, *int32, *int64
  • []int, []int8, []int16, []int32, []int64
  • uint, uint8, uint16, uint32, uint64
  • *uint, *uint8, *uint16, *uint32, *uint64
  • []uint, []uint8, []uint16, []uint32, []uint64
  • url.URL, *url.URL, []url.URL
  • regexp.Regexp, *regexp.Regexp, []regexp.Regexp
  • time.Duration, *time.Duration, []time.Duration

The supported syntax for Regexp is POSIX Regular Expressions.

Skipping

If you want to skip a source for reading values, use - as follows:

type Config struct {
  GithubToken string `env:"-" fileenv:"-"`
}

In the example above, GithubToken can only be set using github.token command-line flag.

Customization

You can use Go struct tags to customize the name of expected command-line flags or environment variables.

type Config struct {
  Database string `flag:"config.database" env:"CONFIG_DATABASE" fileenv:"CONFIG_DATABASE_FILE_PATH"`
}

In the example above, Database will be read from either:

  1. The command-line flag config.databas
  2. The environment variable CONFIG_DATABASE
  3. The file specified by environment variable CONFIG_DATABASE_FILE_PATH
  4. The default value set on struct instance

Using flag Package

konfig plays nice with flag package since it does NOT use flag package for parsing command-line flags. That means you can define, parse, and use your own flags using built-in flag package.

If you use flag package, konfig will also add the command-line flags it is expecting. Here is an example:

package main

import (
  "flag"
  "time"

  "github.com/moorara/konfig"
)

var config = struct {
  Enabled   bool
  LogLevel  string
} {
  Enabled:  true,   // default
  LogLevel: "info", // default
}

func main() {
  konfig.Pick(&config)
  flag.Parse()
}

If you run this example with -help or --help flag, you will see -enabled and -log.level flags are also added with descriptions!

Options

Options are helpers for specific situations and setups. You can pass a list of options to Pick and Watch methods. If you want to test or debug something and you don't want to make code changes, you can set options through environment variables as well.

Option Environment Variable Description
konfig.Debug() KONFIG_DEBUG Printing debugging information.
konfig.ListSep() KONFIG_LIST_SEP Specifying list separator for all fields with slice type.
konfig.SkipFlag() KONFIG_SKIP_FLAG Skipping command-line flags as a source for all fields.
konfig.SkipEnv() KONFIG_SKIP_ENV Skipping environment variables as a source for all fields .
konfig.SkipFileEnv() KONFIG_SKIP_FILE_ENV Skipping file environment variables (and configuration files) as a source for all fields.
konfig.PrefixFlag() KONFIG_PREFIX_FLAG Prefixing all flag names with a string.
konfig.PrefixEnv() KONFIG_PREFIX_ENV Prefixing all environment variable names with a string.
konfig.PrefixFileEnv() KONFIG_PREFIX_FILE_ENV Prefixing all file environment variable names with a string.
konfig.Telepresence() KONFIG_TELEPRESENCE Reading configuration files in a Telepresence environment.

Debugging

If for any reason the configuration values are not read as you expected, you can view the debugging logs. You can enable debugging logs either by using Debug option or by setting KONFIG_DEBUG environment variable. In both cases you need to specify a verbosity level for logs.

Level Descriptions
0 No logging (default).
1 Logging all errors.
2 Logging initialization information.
3 Logging information related to new values read from files.
4 Logging information related to notifying subscribers.
5 Logging information related to setting values of fields.
6 Logging miscellaneous information.

Watching Changes

konfig allows you to watch configuration files and dynamically update your configurations as your application is running.

When using Watch() method, your struct should have a sync.Mutex field on it for synchronization and preventing data races. You can find an example of using Watch() method here.

Here you will find a real-world example of using konfig.Watch() for dynamic configuration management and secret injection for Go applications running in Kubernetes.

About

A Minimal Unopinionated Library For Reading Configurations in Go

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 100.0%