diff --git a/agent/config/config.go b/agent/config/config.go deleted file mode 100644 index 2a41e6be..00000000 --- a/agent/config/config.go +++ /dev/null @@ -1,100 +0,0 @@ -package config - -import ( - "fmt" - "os" - "strings" -) - -const ( - DefaultLogFilePath = "/var/log/datadog/network-tracer.log" - DefaultUnixSocketPath = "/opt/datadog-agent/run/nettracer.sock" -) - -// Config is the global config for the network-tracer. This information is sourced from config files and -// the environment variables. -type Config struct { - Enabled bool - LogFile string - LogLevel string - LogToConsole bool - UnixSocketPath string -} - -// NewDefaultConfig returns an Config with defaults initialized -func NewDefaultConfig() *Config { - return &Config{ - Enabled: false, - LogFile: DefaultLogFilePath, - LogLevel: "info", - LogToConsole: false, - UnixSocketPath: DefaultUnixSocketPath, - } -} - -// NewConfig returns an Config using a configuration file. It can be nil -// if there is no file available. In this case we'll configure only via environment. -func NewConfig(yamlCfg *YamlConfig) (*Config, error) { - var err error - cfg := NewDefaultConfig() - - // For Agents >= 6 we will have a YAML config file to use. - if yamlCfg != nil { - if cfg, err = mergeYamlConfig(cfg, yamlCfg); err != nil { - return nil, err - } - } - - // Use environment to override config values - cfg = mergeEnvironmentVariables(cfg) - - // Python-style log level has WARNING vs WARN - if strings.ToLower(cfg.LogLevel) == "warning" { - cfg.LogLevel = "warn" - } - - // (Re)configure the logging from our configuration - if err := NewLoggerLevel(cfg.LogLevel, cfg.LogFile, cfg.LogToConsole); err != nil { - return nil, err - } - - return cfg, nil -} - -// mergeEnvironmentVariables applies overrides from environment variables to the process agent configuration -func mergeEnvironmentVariables(cfg *Config) *Config { - if enabled, err := isAffirmative(os.Getenv("DD_NETWORK_TRACING_ENABLED")); err == nil { - cfg.Enabled = enabled - } - - // Network tracer unix socket location - if v := os.Getenv("DD_NETTRACER_SOCKET"); v != "" { - cfg.UnixSocketPath = v - } - - // Support LOG_LEVEL and DD_LOG_LEVEL, but prefer DD_LOG_LEVEL - if v := os.Getenv("LOG_LEVEL"); v != "" { - cfg.LogLevel = v - } - if v := os.Getenv("DD_LOG_LEVEL"); v != "" { - cfg.LogLevel = v - } - - // Support DD_LOGS_STDOUT and LOG_TO_CONSOLE, but prefer LOG_TO_CONSOLE - if enabled, err := isAffirmative(os.Getenv("DD_LOGS_STDOUT")); err == nil { - cfg.LogToConsole = enabled - } - if enabled, err := isAffirmative(os.Getenv("LOG_TO_CONSOLE")); err == nil { - cfg.LogToConsole = enabled - } - - return cfg -} - -func isAffirmative(value string) (bool, error) { - if value == "" { - return false, fmt.Errorf("value is empty") - } - v := strings.ToLower(value) - return v == "true" || v == "yes" || v == "1", nil -} diff --git a/agent/config/log.go b/agent/config/log.go deleted file mode 100644 index f2bb02df..00000000 --- a/agent/config/log.go +++ /dev/null @@ -1,295 +0,0 @@ -package config - -import ( - "encoding/xml" - "errors" - "fmt" - "os" - "strconv" - "strings" - "time" - - log "github.com/cihub/seelog" -) - -var ( - levelToSyslogSeverity = map[log.LogLevel]int{ - log.TraceLvl: 7, - log.DebugLvl: 7, - log.InfoLvl: 6, - log.WarnLvl: 4, - log.ErrorLvl: 3, - log.CriticalLvl: 2, - log.Off: 7, - } - - errInvalidLogLevel = errors.New("invalid log level") -) - -type seelogConfig struct { - XMLName xml.Name `xml:"seelog"` - LogLevel string `xml:"minlevel,attr"` - *seelogOutputs - *seelogFormats -} - -type seelogOutputs struct { - Filters []seelogFilter `xml:"outputs>filter"` -} - -type seelogFilter struct { - XMLName xml.Name `xml:"filter,omitempty"` - Levels string `xml:"levels,attr,omitempty"` - Syslog *seelogFilterAttrs `xml:"conn"` - Console *seelogFilterAttrs `xml:"console"` - RollingFile *seelogFilterAttrs `xml:"rollingfile"` -} - -type seelogFilterAttrs struct { - FormatID string `xml:"formatid,attr,omitempty"` - - // - Net string `xml:"net,attr,omitempty"` - Addr string `xml:"addr,attr,omitempty"` - - // - Filename string `xml:"filename,attr,omitempty"` - Type string `xml:"type,attr,omitempty"` - MaxSize int `xml:"maxsize,attr,omitempty"` - MaxRolls int `xml:"maxrolls,attr,omitempty"` -} - -type seelogFormats struct { - Formats []seelogFormat `xml:"formats>format"` -} - -type seelogFormat struct { - ID string `xml:"id,attr"` - Format string `xml:"format,attr"` -} - -func newConsoleFormat() *seelogFormat { - return &seelogFormat{ - ID: "console", - Format: "%Date %Time %LEVEL (%File:%Line) - %Msg%n", - } -} - -func newSyslogFormat() *seelogFormat { - return &seelogFormat{ - ID: "syslog", - Format: "%CustomSyslogHeader(20) %Msg%n", - } -} - -func newFileFormat() *seelogFormat { - return &seelogFormat{ - ID: "file", - Format: "%Date %Time %LEVEL (%File:%Line) - %Msg%n", - } -} - -var syslogFormatter log.FormatterFuncCreator - -func registerSyslogFormatter(appName string) error { - hostName := getSyslogHostname() - pid := os.Getpid() - - if syslogFormatter == nil { - err := log.RegisterCustomFormatter("CustomSyslogHeader", func(params string) log.FormatterFunc { - return syslogFormatter(params) - }) - if err != nil { - return err - } - } - - syslogFormatter = func(params string) log.FormatterFunc { - facility := 20 - i, err := strconv.Atoi(params) - if err == nil && i >= 0 && i <= 23 { - facility = i - } - return func(message string, level log.LogLevel, context log.LogContextInterface) interface{} { - return fmt.Sprintf("<%d>1 %s %s %s %d - -", facility*8+levelToSyslogSeverity[level], - time.Now().Format("2006-01-02T15:04:05Z07:00"), hostName, appName, pid) - } - } - - return nil -} - -func newSyslogFilter(host, logLvl string) *seelogFilter { - return &seelogFilter{ - Levels: filterLevels(logLvl), - Syslog: &seelogFilterAttrs{ - FormatID: "syslog", - Net: "udp", - Addr: host, - }, - } -} - -func newConsoleFilter(logLvl string) *seelogFilter { - return &seelogFilter{ - Levels: filterLevels(logLvl), - Console: &seelogFilterAttrs{ - FormatID: "console", - }, - } -} - -func newFileFilter(logLvl, filename string) *seelogFilter { - return &seelogFilter{ - Levels: filterLevels(logLvl), - RollingFile: &seelogFilterAttrs{ - FormatID: "file", - Filename: filename, - Type: "size", - MaxSize: 10 * 1024 * 1024, - MaxRolls: 1, - }, - } -} - -func newSeelog() *seelogConfig { - return &seelogConfig{ - // Filters override this value - LogLevel: "debug", - seelogOutputs: &seelogOutputs{}, - seelogFormats: &seelogFormats{}, - } -} - -func (s *seelogConfig) addFormat(f *seelogFormat) { - s.Formats = append(s.Formats, *f) -} - -func (s *seelogConfig) addFilter(f *seelogFilter) { - s.Filters = append(s.Filters, *f) -} - -func (s *seelogConfig) addSyslog(appName, addr, logLvl string) error { - if err := registerSyslogFormatter(appName); err != nil { - return err - } - s.addFilter(newSyslogFilter(addr, logLvl)) - s.addFormat(newSyslogFormat()) - return nil -} - -func (s *seelogConfig) addConsole(logLvl string) { - s.addFilter(newConsoleFilter(logLvl)) - s.addFormat(newConsoleFormat()) -} - -func (s *seelogConfig) addFile(logLvl, filename string) { - s.addFilter(newFileFilter(logLvl, filename)) - s.addFormat(newFileFormat()) -} - -func (cfg *LoggerConfig) seelogConfig() (*seelogConfig, error) { - s := newSeelog() - - if cfg.Filename != "" { - s.addFile(cfg.LogLevel, cfg.Filename) - } - if cfg.Console { - s.addConsole(cfg.LogLevel) - } - if cfg.Syslog { - if err := s.addSyslog("nettracer", cfg.SyslogHost, cfg.SyslogLevel); err != nil { - return nil, err - } - } - - return s, nil -} - -// LoggerConfig defines the configuration of a logger -type LoggerConfig struct { - AppName string - LogLevel string - Console bool - Syslog bool - SyslogLevel string - SyslogHost string - Filename string -} - -// SeelogLogger returns a new seelog Logger -func (cfg *LoggerConfig) SeelogLogger() (log.LoggerInterface, error) { - scfg, err := cfg.seelogConfig() - if err != nil { - return nil, err - } - - xmlConfig, err := xml.MarshalIndent(scfg, "", " ") - if err != nil { - return nil, err - } - - return log.LoggerFromConfigAsString(string(xmlConfig)) -} - -func filterLevels(level string) string { - // https://github.com/cihub/seelog/wiki/Log-levels - if level == "off" { - return "off" - } - levels := "trace,debug,info,warn,error,critical" - return levels[strings.Index(levels, level):] -} - -func getSyslogHostname() string { - hostname, err := os.Hostname() - if err != nil { - return "unknown" - } - return hostname -} - -func validateLogLevels(levels ...string) error { - logLevels := map[string]struct{}{ - "trace": {}, - "debug": {}, - "info": {}, - "warn": {}, - "error": {}, - "critical": {}, - "off": {}, - } - - for _, level := range levels { - if _, ok := logLevels[level]; !ok { - return errInvalidLogLevel - } - } - return nil -} - -func replaceLogger(cfg *LoggerConfig) error { - if err := validateLogLevels(cfg.LogLevel); err == errInvalidLogLevel { - log.Infof("log level %s is invalid, defaulting to INFO") - cfg.LogLevel = "info" - } - if err := validateLogLevels(cfg.SyslogLevel); err == errInvalidLogLevel { - log.Infof("log level %s is invalid, defaulting to INFO") - cfg.LogLevel = "info" - } - logger, err := cfg.SeelogLogger() - if err != nil { - return err - } - return log.ReplaceLogger(logger) -} - -// NewLoggerLevel sets the global logger to the given log level. -func NewLoggerLevel(logLevel, logFile string, logToConsole bool) error { - return replaceLogger(&LoggerConfig{ - LogLevel: strings.ToLower(logLevel), - Filename: logFile, - SyslogLevel: "off", - Console: logToConsole, - }) -} diff --git a/agent/config/log_test.go b/agent/config/log_test.go deleted file mode 100644 index bb16badc..00000000 --- a/agent/config/log_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package config - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestLogLevelCase(t *testing.T) { - assert.NoError(t, NewLoggerLevel("DEBUG", DefaultLogFilePath, false)) - assert.NoError(t, NewLoggerLevel("debug", DefaultLogFilePath, false)) - assert.NoError(t, NewLoggerLevel("InFo", DefaultLogFilePath, false)) - assert.NoError(t, NewLoggerLevel("INFO", DefaultLogFilePath, false)) - assert.NoError(t, NewLoggerLevel("WARN", DefaultLogFilePath, false)) - assert.NoError(t, NewLoggerLevel("WARNING", DefaultLogFilePath, false)) - assert.NoError(t, NewLoggerLevel("notReal", DefaultLogFilePath, false)) -} diff --git a/agent/config/yaml_config.go b/agent/config/yaml_config.go deleted file mode 100644 index c3446e88..00000000 --- a/agent/config/yaml_config.go +++ /dev/null @@ -1,89 +0,0 @@ -package config - -import ( - "bufio" - "fmt" - "os" - "strings" - - "gopkg.in/yaml.v2" -) - -// YamlConfig is a structure used for marshaling the datadog.yaml configuration -// available in Agent versions >= 6 -type YamlConfig struct { - Network struct { - // A string indicating the enabled state of the network tracer. - NetworkTracingEnabled string `yaml:"network_tracing_enabled"` - // The full path to the file where network-tracer logs will be written. - LogFile string `yaml:"log_file"` - // Boolean whether the logs should also be output to stdout - LogToConsole bool `yaml:"log_to_console"` - // String indicating log level (e.g. info, debug, warn) - LogLevel string `yaml:"log_level"` - // The full path to the location of the unix socket where network traces will be accessed - UnixSocketPath string `yaml:"nettracer_socket"` - } `yaml:"network_tracer_config"` -} - -// NewYamlIfExists returns a new YamlConfig if the given configPath is exists. -func NewYamlIfExists(configPath string) (*YamlConfig, error) { - yamlConf := YamlConfig{} - if pathExists(configPath) { - lines, err := readLines(configPath) - if err != nil { - return nil, fmt.Errorf("read error: %s", err) - } - if err = yaml.Unmarshal([]byte(strings.Join(lines, "\n")), &yamlConf); err != nil { - return nil, fmt.Errorf("parse error: %s", err) - } - return &yamlConf, nil - } - return nil, nil -} - -func mergeYamlConfig(agentConf *Config, yc *YamlConfig) (*Config, error) { - if enabled, err := isAffirmative(yc.Network.NetworkTracingEnabled); err == nil { - agentConf.Enabled = enabled - } - - if socketPath := yc.Network.UnixSocketPath; socketPath != "" { - agentConf.UnixSocketPath = socketPath - } - - if yc.Network.LogToConsole { - agentConf.LogToConsole = true - } - if yc.Network.LogFile != "" { - agentConf.LogFile = yc.Network.LogFile - } - - // Pull additional parameters from the global config file. - agentConf.LogLevel = yc.Network.LogLevel - - return agentConf, nil -} - -// pathExists returns a boolean indicating if the given path exists on the file system. -func pathExists(filename string) bool { - if _, err := os.Stat(filename); err == nil { - return true - } - return false -} - -// readLines reads contents from a file and splits them by new lines. -func readLines(filename string) ([]string, error) { - f, err := os.Open(filename) - if err != nil { - return []string{""}, err - } - defer f.Close() - - var ret []string - scanner := bufio.NewScanner(f) - for scanner.Scan() { - ret = append(ret, scanner.Text()) - } - return ret, scanner.Err() -} diff --git a/agent/main.go b/agent/main.go deleted file mode 100644 index 8788ef0e..00000000 --- a/agent/main.go +++ /dev/null @@ -1,152 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "os" - "os/signal" - "strings" - "syscall" - "time" - - log "github.com/cihub/seelog" - - "github.com/DataDog/datadog-agent/pkg/pidfile" - "github.com/DataDog/tcptracer-bpf/agent/config" -) - -// Flag values -var opts struct { - configPath string - - pidFilePath string - debug bool - version bool -} - -// Version info sourced from build flags -var ( - GoVersion string - Version string - GitCommit string - GitBranch string - BuildDate string -) - -func main() { - // Parse flags - flag.StringVar(&opts.configPath, "config", "/etc/datadog-agent/network-tracer.yaml", "Path to network-tracer config formatted as YAML") - flag.StringVar(&opts.pidFilePath, "pid", "", "Path to set pidfile for process") - flag.BoolVar(&opts.version, "version", false, "Print the version and exit") - flag.Parse() - - // Set up a default config before parsing config so we log errors nicely. - // The default will be stdout since we can't assume any file is writeable. - if err := config.NewLoggerLevel("info", "", true); err != nil { - panic(err) - } - defer log.Flush() - - // --version - if opts.version { - fmt.Println(versionString()) - os.Exit(0) - } - - // --pid - if opts.pidFilePath != "" { - if err := pidfile.WritePID(opts.pidFilePath); err != nil { - log.Errorf("Error while writing PID file, exiting: %v", err) - os.Exit(1) - } - - log.Infof("pid '%d' written to pid file '%s'", os.Getpid(), opts.pidFilePath) - - defer func() { - os.Remove(opts.pidFilePath) - }() - } - - // Parsing INI and/or YAML config files - cfg := parseConfig() - - // Exit if network tracer is disabled - if !cfg.Enabled { - log.Info("network tracer not enabled. exiting.") - gracefulExit() - } - - nettracer, err := CreateNetworkTracer(cfg) - if err != nil && strings.HasPrefix(err.Error(), TracerUnsupportedError.Error()) { - // If tracer is unsupported by this operating system, then exit gracefully - log.Infof("%s, exiting.", err) - gracefulExit() - } else if err != nil { - log.Criticalf("failed to create network tracer: %s", err) - os.Exit(1) - } - defer nettracer.Close() - - go nettracer.Run() - log.Infof("network tracer started") - - // Handles signals, which tells us whether we should exit. - e := make(chan bool) - go handleSignals(e) - <-e -} - -func gracefulExit() { - // A sleep is necessary to ensure that supervisor registers this process as "STARTED" - // If the exit is "too quick", we enter a BACKOFF->FATAL loop even though this is an expected exit - // http://supervisord.org/subprocess.html#process-states - time.Sleep(5 * time.Second) - os.Exit(0) -} - -func handleSignals(exit chan bool) { - sigIn := make(chan os.Signal, 100) - signal.Notify(sigIn) - // unix only in all likelihood; but we don't care. - for sig := range sigIn { - switch sig { - case syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGQUIT: - log.Criticalf("Caught signal '%s'; terminating.", sig) - close(exit) - default: - } - } -} - -// versionString returns the version information filled in at build time -func versionString() string { - addString := func(buf *bytes.Buffer, s, arg string) { - if arg != "" { - fmt.Fprintf(buf, s, arg) - } - } - - var buf bytes.Buffer - addString(&buf, "Version: %s\n", Version) - addString(&buf, "Git hash: %s\n", GitCommit) - addString(&buf, "Git branch: %s\n", GitBranch) - addString(&buf, "Build date: %s\n", BuildDate) - addString(&buf, "Go Version: %s\n", GoVersion) - return buf.String() -} - -func parseConfig() *config.Config { - yamlConf, err := config.NewYamlIfExists(opts.configPath) // --yamlConfig - if err != nil { // Will return nil if no Yaml file exists - log.Criticalf("Error reading YAML formatted config: %s", err) - os.Exit(1) - } - - cfg, err := config.NewConfig(yamlConf) - if err != nil { - log.Criticalf("Error parsing config: %s", err) - os.Exit(1) - } - return cfg -} diff --git a/agent/net/common.go b/agent/net/common.go deleted file mode 100644 index 6a81aa57..00000000 --- a/agent/net/common.go +++ /dev/null @@ -1,11 +0,0 @@ -package net - -import "net" - -type Conn interface { - // GetListener returns the underlying net.Listener - GetListener() net.Listener - - // Stop and clean up resources for the underlying connection - Stop() -} diff --git a/agent/net/uds.go b/agent/net/uds.go deleted file mode 100644 index f4a19a70..00000000 --- a/agent/net/uds.go +++ /dev/null @@ -1,60 +0,0 @@ -package net - -import ( - "fmt" - "net" - "os" - - log "github.com/cihub/seelog" - - "github.com/DataDog/tcptracer-bpf/agent/config" -) - -// Unix Domain Socket Listener -type UDSListener struct { - conn net.Listener - socketPath string -} - -// NewUDSListener returns an idle UDSListener Statsd listener -func NewUDSListener(cfg *config.Config) (*UDSListener, error) { - if len(cfg.UnixSocketPath) == 0 { - return nil, fmt.Errorf("nettracer-uds: empty socket path provided") - } - - addr, err := net.ResolveUnixAddr("unix", cfg.UnixSocketPath) - if err != nil { - return nil, fmt.Errorf("nettracer-uds: can't ResolveUnixAddr: %v", err) - } - - conn, err := net.Listen("unix", addr.Name) - if err != nil { - return nil, fmt.Errorf("can't listen: %s", err) - } - - if err := os.Chmod(cfg.UnixSocketPath, 0722); err != nil { - return nil, fmt.Errorf("can't set the socket at write only: %s", err) - } - - listener := &UDSListener{ - conn: conn, - socketPath: cfg.UnixSocketPath, - } - - log.Debugf("nettracer-uds: %s successfully initialized", conn.Addr()) - return listener, nil -} - -func (l *UDSListener) GetListener() net.Listener { - return l.conn -} - -// Stop closes the UDSListener connection and stops listening -func (l *UDSListener) Stop() { - l.conn.Close() - - // Socket cleanup on exit - above conn.Close() should remove it, but just in case. - if err := os.Remove(l.socketPath); err != nil { - log.Debugf("nettracer-uds: error removing socket file: %s", err) - } -} diff --git a/agent/tracer.go b/agent/tracer.go deleted file mode 100644 index 52e74484..00000000 --- a/agent/tracer.go +++ /dev/null @@ -1,86 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "net/http" - "os" - "path/filepath" - - log "github.com/cihub/seelog" - "github.com/mailru/easyjson" - - "github.com/DataDog/tcptracer-bpf/agent/config" - "github.com/DataDog/tcptracer-bpf/agent/net" - "github.com/DataDog/tcptracer-bpf/pkg/tracer" -) - -var TracerUnsupportedError = errors.New("tracer unsupported") - -type NetworkTracer struct { - cfg *config.Config - - supported bool - tracer *tracer.Tracer - conn net.Conn -} - -func CreateNetworkTracer(cfg *config.Config) (*NetworkTracer, error) { - var err error - nt := &NetworkTracer{} - - // Checking whether the current OS + kernel version is supported by the tracer - if nt.supported, err = tracer.IsTracerSupportedByOS(); err != nil { - return nil, fmt.Errorf("%s: %s", TracerUnsupportedError, err) - } - - log.Infof("Creating tracer for: %s", filepath.Base(os.Args[0])) - t, err := tracer.NewTracer(tracer.DefaultConfig) - if err != nil { - return nil, err - } - - // Setting up the unix socket - uds, err := net.NewUDSListener(cfg) - if err != nil { - return nil, err - } - - nt.tracer = t - nt.cfg = cfg - nt.conn = uds - return nt, nil -} - -func (nt *NetworkTracer) Run() { - nt.tracer.Start() - - http.HandleFunc("/status", func(w http.ResponseWriter, req *http.Request) {}) - - http.HandleFunc("/connections", func(w http.ResponseWriter, req *http.Request) { - cs, err := nt.tracer.GetActiveConnections() - - if err != nil { - log.Errorf("unable to retrieve connections: %s", err) - w.WriteHeader(500) - return - } - - buf, err := easyjson.Marshal(cs) - if err != nil { - log.Errorf("unable to marshall connections into JSON: %s", err) - w.WriteHeader(500) - return - } - - w.Write(buf) - log.Debugf("/connections: %d connections, %d bytes", len(cs.Conns), len(buf)) - }) - - http.Serve(nt.conn.GetListener(), nil) -} - -func (nt *NetworkTracer) Close() { - nt.conn.Stop() - nt.tracer.Stop() -} diff --git a/pkg/build_ddagent_release.sh b/pkg/build_ddagent_release.sh deleted file mode 100755 index f025beb4..00000000 --- a/pkg/build_ddagent_release.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -set -xe - -cd $WORKSPACE/go/src/github.com/DataDog/tcptracer-bpf - -# Verify we have the correct environment variables -if [ -z ${AGENT_S3_BUCKET+x} ]; then - echo "Missing AGENT_S3_BUCKET in environment" - exit 1; -fi - -if [ -z ${AGENT_VERSION+x} ]; then - git checkout dd - # Pick the latest tag by default for our version. - AGENT_VERSION=$(git tag | sort | head -1) - # But we will be building from the master branch in this case. - FILENAME="network-tracer-amd64-master" -else - git checkout $AGENT_VERSION - # If we have a version then we'll use it and put it in the name. - FILENAME="network-tracer-amd64-$AGENT_VERSION" -fi - -echo "Building network-tracer agent v$AGENT_VERSION to $FILENAME" - -# Expects gimme to be installed -eval "$(gimme 1.10.1)" - -export GOPATH=$WORKSPACE/go -export PATH=$PATH:$GOPATH/bin - -echo "Building binaries..." -NETWORK_AGENT_STATIC=true make build-agent - -# Upload to s3 -cp network-tracer $FILENAME -s3cmd sync -v ./$FILENAME s3://$AGENT_S3_BUCKET/