<commit_before># doozerconfig

## What Is It?

doozerconfig is a Go package to load json-encoded configuration from doozer into a native Go struct type. It also monitors for any changes to the configuration and automatically updates the struct.

## Example

```Go
var Config struct {
    MaxRecordSize    int    `doozer:"logyard/config/max_record_size"`
    MaxRecordsPerApp int    `doozer:"logyard/config/max_records_per_app"`
    NatsUri          string `doozer:"cloud_controller/config/mbus"`
    RedisHost        string `doozer:"cloud_controller/config/redis/host"`
    RedisPort        int    `doozer:"cloud_controller/config/redis/port"`
    RedisUri         string
    Verbose          bool
}

func init() {
    doozer, err := doozer.Dial(getDoozerURI())
    if err != nil {
	log.Fatal(err)
    }

    headRev, err := doozer.Rev()
    if err != nil {
	log.Fatal(err)
    }

    cfg := doozerconfig.New(doozer, &Config, "/proc/")
    err = cfg.Load()  // this populates the Config struct
    if err != nil {
	log.Fatal(err)
    }
    Config.RedisUri = fmt.Sprintf("%s:%d", Config.RedisHost, Config.RedisPort)

    // watch to live changes to doozer config
    go func() {
        // Monitor updates the struct on any relevant changes in doozer
	for change := range cfg.Monitor("/proc/logyard/config/*", headRev) {
	    log.Printf("config changed in doozer; %s=%v\n", change.Field.Name, change.Value.Interface())
	}
    }()
}
```
<commit_msg>more touches to README.md<commit_after># doozerconfig

## What Is It?

doozerconfig is a Go package for managing json-encoded configuration in doozer. Configuration is directly loaded into a Go struct (see example below). Using struct tags to define the doozer path, the package will automatically read, json-decode and assign the values to the corresponding struct fields. You can also watch for future changes to doozer config and have the struct automatically update.

In future, this package will also provide a way to write configuration back to doozer.

## Example

```Go
var Config struct {
    MaxRecordSize    int    `doozer:"logyard/config/max_record_size"`
    MaxRecordsPerApp int    `doozer:"logyard/config/max_records_per_app"`
    NatsUri          string `doozer:"cloud_controller/config/mbus"`
    RedisHost        string `doozer:"cloud_controller/config/redis/host"`
    RedisPort        int    `doozer:"cloud_controller/config/redis/port"`
    RedisUri         string // not in doozer
    Verbose          bool   // not in doozer
}

func init() {
    doozer, err := doozer.Dial(getDoozerURI())
    if err != nil {
        log.Fatal(err)
    }

    headRev, err := doozer.Rev()
    if err != nil {
        log.Fatal(err)
    }

    cfg := doozerconfig.New(doozer, &Config, "/proc/")
    err = cfg.Load()  // this populates the Config struct
    if err != nil {
        log.Fatal(err)
    }
    Config.RedisUri = fmt.Sprintf("%s:%d", Config.RedisHost, Config.RedisPort)

    // watch for live changes to doozer config
    go func() {
        // Monitor updates the struct on any relevant changes in doozer
        for change := range cfg.Monitor("/proc/logyard/config/*", headRev) {
            log.Printf("config changed in doozer; %s=%v\n", change.Field.Name, change.Value.Interface())
        }
    }()
}
```

{'fraction_non_alphanumeric': 0.10870229007633588, 'fraction_numerical': 0.0, 'mean_word_length': 2.913978494623656, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3536910', 'n_tokens_mistral': 1036, 'n_tokens_neox': 1019, 'n_words': 306}