Skip to content

Commit

Permalink
Merge pull request #65 from kensimon/podlog-limits
Browse files Browse the repository at this point in the history
Allow configuring size/time limits for pod logs
  • Loading branch information
Ken Simon authored Aug 31, 2017
2 parents 515ccab + 805b09e commit 8d8cb15
Show file tree
Hide file tree
Showing 12 changed files with 522 additions and 3 deletions.
4 changes: 4 additions & 0 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cmd/sonobuoy/app/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/heptio/sonobuoy/pkg/config"
"github.com/heptio/sonobuoy/pkg/discovery"
"github.com/heptio/sonobuoy/pkg/errlog"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
Expand All @@ -47,7 +48,7 @@ func runMaster(cmd *cobra.Command, args []string) {

cfg, err := config.LoadConfig()
if err != nil {
errlog.LogError(err)
errlog.LogError(errors.Wrap(err, "error loading sonobuoy configuration"))
os.Exit(1)
}

Expand Down
7 changes: 7 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ See [Parameter Reference][3] for a more detailed description of each setting.
"LabelSelector": "",
"Namespaces": ".*"
},
"Limits": {
"PodLogs": {
"LimitTime": "24h"
}
},
"Server": {
"advertiseaddress": "",
"bindaddress": "0.0.0.0",
Expand All @@ -105,6 +110,8 @@ See [Parameter Reference][3] for a more detailed description of each setting.
| Resources | String Array | An array containing all possible resources | *See the [sample JSON][2] above for a list of all available resource types.*<br><br>Indicates to Sonobuoy what type of data it should be recording |
| Filters.LabelSelector | String | "" | Uses standard Kubernetes [label selector syntax][14] to filter which resource objects are recorded |
| Filters.Namespaces | String | ".*" | Uses regex on namespaces to filter which resource objects are recorded |
| Limits.PodLogs.LimitTime | String | "" | Limits how far back in time to gather Pod Logs, leave blank for no limit (e.g. "24h", "60m". See https://golang.org/pkg/time/#ParseDuration for details.) |
| Limits.PodLogs.LimitSize | String | "" | Limits the size of Pod Logs to gather, per container, leave blank for no limit (e.g. "10 MB", "1 GB", etc.) |
| Server.advertiseaddress | String | `$SONOBUOY_ADVERTISE_IP` &#124;&#124; the current server's `os.Hostname()`| *Only used if Sonobuoy dispatches agent pods to collect node-specific information*<br><br>The IP address that remote Sonobuoy agents send information back to, in order for disparate data to be aggregated into a single report |
| Server.bindaddress | String | "0.0.0.0" | *See `Server.advertiseaddress` for context.*<br><br>If data aggregation is required, an HTTP server is started to handle the worker requests. This is the address that server binds to. |
| Server.bindport | Int | 8080 | The port for the HTTP server mentioned in *Server.bindaddress*. |
Expand Down
62 changes: 62 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ package config

import (
"path"
"time"

"github.com/c2h5oh/datasize"
"github.com/heptio/sonobuoy/pkg/buildinfo"
"github.com/heptio/sonobuoy/pkg/plugin"
"github.com/satori/go.uuid"
Expand Down Expand Up @@ -111,6 +113,8 @@ type Config struct {
///////////////////////////////////////////////
Filters FilterOptions `json:"Filters" mapstructure:"Filters"`

Limits LimitConfig `json:"Limits" mapstructure:"Limits"`

///////////////////////////////////////////////
// plugin configurations settings
///////////////////////////////////////////////
Expand All @@ -121,6 +125,18 @@ type Config struct {
LoadedPlugins []plugin.Interface // this is assigned when plugins are loaded.
}

// LimitConfig is a configuration on the limits of sizes of various responses.
type LimitConfig struct {
PodLogs SizeOrTimeLimitConfig `json:"PodLogs" mapstructure:"PodLogs"`
}

// SizeOrTimeLimitConfig represents configuration that limits the size of
// something either by a total disk size, or by a length of time.
type SizeOrTimeLimitConfig struct {
LimitSize string `json:"LimitSize" mapstructure:"LimitSize"`
LimitTime string `json:"LimitTime" mapstructure:"LimitTime"`
}

// FilterResources is a utility function used to parse Resources
func (cfg *Config) FilterResources(filter []string) map[string]bool {
results := make(map[string]bool)
Expand All @@ -141,6 +157,52 @@ func (cfg *Config) OutputDir() string {
return path.Join(cfg.ResultsDir, cfg.UUID)
}

// SizeLimitBytes returns how many bytes the configuration is set to limit,
// returning defaultVal if not set.
func (c SizeOrTimeLimitConfig) SizeLimitBytes(defaultVal int64) int64 {
val, defaulted, err := c.sizeLimitBytes()

// Ignore error, since we should have already caught it in validation
if err != nil || defaulted {
return defaultVal
}

return val
}

func (c SizeOrTimeLimitConfig) sizeLimitBytes() (val int64, defaulted bool, err error) {
str := c.LimitSize
if str == "" {
return 0, true, nil
}

var bs datasize.ByteSize
err = bs.UnmarshalText([]byte(str))
return int64(bs.Bytes()), false, err
}

// TimeLimitDuration returns the duration the configuration is set to limit, returning defaultVal if not set.
func (c SizeOrTimeLimitConfig) TimeLimitDuration(defaultVal time.Duration) time.Duration {
val, defaulted, err := c.timeLimitDuration()

// Ignore error, since we should have already caught it in validation
if err != nil || defaulted {
return defaultVal
}

return val
}

func (c SizeOrTimeLimitConfig) timeLimitDuration() (val time.Duration, defaulted bool, err error) {
str := c.LimitTime
if str == "" {
return 0, true, nil
}

val, err = time.ParseDuration(str)
return val, false, err
}

// NewWithDefaults returns a newly-constructed Config object with default values.
func NewWithDefaults() *Config {
var cfg Config
Expand Down
28 changes: 28 additions & 0 deletions pkg/config/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package config
import (
"fmt"
"os"
"strings"

"github.com/heptio/sonobuoy/pkg/buildinfo"
"github.com/heptio/sonobuoy/pkg/plugin"
Expand Down Expand Up @@ -89,10 +90,37 @@ func LoadConfig() (*Config, error) {

// 5 - Load any plugins we have
err = loadAllPlugins(cfg)
if err != nil {
return nil, err
}

// 6 - Return any validation errors
validationErrs := cfg.Validate()
if len(validationErrs) > 0 {
errstrs := make([]string, len(validationErrs))
for i := range validationErrs {
errstrs[i] = validationErrs[i].Error()
}

return nil, errors.Errorf("invalid configuration: %v", strings.Join(errstrs, ", "))
}

return cfg, err
}

// Validate returns a list of errors for the configuration, if any are found.
func (cfg *Config) Validate() (errors []error) {
if _, defaulted, err := cfg.Limits.PodLogs.sizeLimitBytes(); err != nil && !defaulted {
errors = append(errors, err)
}

if _, defaulted, err := cfg.Limits.PodLogs.timeLimitDuration(); err != nil && !defaulted {
errors = append(errors, err)
}

return errors
}

// LoadClient creates a kube-clientset, using given sonobuoy configuration
func LoadClient(cfg *Config) (kubernetes.Interface, error) {
var config *rest.Config
Expand Down
9 changes: 7 additions & 2 deletions pkg/discovery/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import (
"io/ioutil"
"os"
"path"
"time"

"github.com/sirupsen/logrus"
"github.com/heptio/sonobuoy/pkg/config"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
Expand All @@ -44,6 +45,8 @@ func gatherPodLogs(kubeClient kubernetes.Interface, ns string, opts metav1.ListO
}

logrus.Info("Collecting Pod Logs...")
limitBytes := cfg.Limits.PodLogs.SizeLimitBytes(0)
limitTime := int64(cfg.Limits.PodLogs.TimeLimitDuration(0) / time.Second)

// 2 - Foreach pod, dump each of its containers' logs in a tree in the following location:
// pods/:podname/logs/:containername.txt
Expand All @@ -52,7 +55,9 @@ func gatherPodLogs(kubeClient kubernetes.Interface, ns string, opts metav1.ListO
body, err := kubeClient.CoreV1().Pods(ns).GetLogs(
pod.Name,
&v1.PodLogOptions{
Container: container.Name,
Container: container.Name,
LimitBytes: &limitBytes,
SinceSeconds: &limitTime,
},
).Do().Raw()

Expand Down
24 changes: 24 additions & 0 deletions vendor/github.com/c2h5oh/datasize/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions vendor/github.com/c2h5oh/datasize/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions vendor/github.com/c2h5oh/datasize/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions vendor/github.com/c2h5oh/datasize/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8d8cb15

Please sign in to comment.