From ae1c506a49466c11829c8f676971f0389123b57b Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Sat, 4 Mar 2023 10:46:33 +0100 Subject: [PATCH 1/6] optimize release binary & add build for debugging --- custom-tests/build-delve/build.sh | 8 ++++++++ custom-tests/init/var/rapid/entrypoint.sh | 5 +++++ 2 files changed, 13 insertions(+) create mode 100755 custom-tests/build-delve/build.sh create mode 100755 custom-tests/init/var/rapid/entrypoint.sh diff --git a/custom-tests/build-delve/build.sh b/custom-tests/build-delve/build.sh new file mode 100755 index 0000000..69f6a2b --- /dev/null +++ b/custom-tests/build-delve/build.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +mkdir -p /tmp/build-delve +cd /tmp/build-delve +git clone https://github.com/go-delve/delve.git +cd delve +make build +mv dlv /app/dlv \ No newline at end of file diff --git a/custom-tests/init/var/rapid/entrypoint.sh b/custom-tests/init/var/rapid/entrypoint.sh new file mode 100755 index 0000000..2819c9a --- /dev/null +++ b/custom-tests/init/var/rapid/entrypoint.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +LAMBDA_INIT_DELVE_PORT="${LAMBDA_INIT_DELVE_PORT:-40000}" + +exec /var/rapid/dlv --listen=:${LAMBDA_INIT_DELVE_PORT} --headless=true --api-version=2 --accept-multiclient exec /var/rapid/init \ No newline at end of file From d04998406c6a073158937a1b423c72b7d796ec82 Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Fri, 17 Mar 2023 10:27:30 +0100 Subject: [PATCH 2/6] start xray daemon if request is sampled --- cmd/localstack/awsutil.go | 28 +- cmd/localstack/custom_interop.go | 9 +- cmd/localstack/main.go | 67 ++++- cmd/localstack/xraydaemon.go | 301 ++++++++++++++++++++++ custom-tests/build-delve/build.sh | 8 - custom-tests/init/var/rapid/entrypoint.sh | 5 - debugging/init/var/rapid/entrypoint.sh | 1 + go.mod | 16 +- go.sum | 35 ++- 9 files changed, 409 insertions(+), 61 deletions(-) create mode 100644 cmd/localstack/xraydaemon.go delete mode 100755 custom-tests/build-delve/build.sh delete mode 100755 custom-tests/init/var/rapid/entrypoint.sh diff --git a/cmd/localstack/awsutil.go b/cmd/localstack/awsutil.go index 1007458..529bb99 100644 --- a/cmd/localstack/awsutil.go +++ b/cmd/localstack/awsutil.go @@ -8,7 +8,6 @@ package main import ( "context" "fmt" - "github.com/jessevdk/go-flags" log "github.com/sirupsen/logrus" "go.amzn.com/lambda/interop" "go.amzn.com/lambda/rapidcore" @@ -27,29 +26,12 @@ const ( runtimeBootstrap = "/var/runtime/bootstrap" ) -type options struct { - LogLevel string `long:"log-level" default:"info" description:"log level"` - InitCachingEnabled bool `long:"enable-init-caching" description:"Enable support for Init Caching"` -} - -func getCLIArgs() (options, []string) { - var opts options - parser := flags.NewParser(&opts, flags.IgnoreUnknown) - args, err := parser.ParseArgs(os.Args) - - if err != nil { - log.WithError(err).Fatal("Failed to parse command line arguments:", os.Args) - } - - return opts, args -} - func isBootstrapFileExist(filePath string) bool { file, err := os.Stat(filePath) return !os.IsNotExist(err) && !file.IsDir() } -func getBootstrap(args []string, opts options) (*rapidcore.Bootstrap, string) { +func getBootstrap(args []string) (*rapidcore.Bootstrap, string) { var bootstrapLookupCmd []string var handler string currentWorkingDir := "/var/task" // default value @@ -148,7 +130,7 @@ func resetListener(changeChannel <-chan bool, server *CustomInteropServer) { func RunDNSRewriter(opts *LsOpts, ctx context.Context) { if opts.EnableDnsServer != "1" { - log.Debugln("Dns server disabled") + log.Debugln("DNS server disabled. S") return } dnsForwarder, err := NewDnsForwarder(opts.LocalstackIP) @@ -160,7 +142,7 @@ func RunDNSRewriter(opts *LsOpts, ctx context.Context) { dnsForwarder.Start() <-ctx.Done() - log.Debugln("Shutting down dns server") + log.Debugln("DNS server stopped") } func RunHotReloadingListener(server *CustomInteropServer, targetPaths []string, ctx context.Context) { @@ -234,11 +216,11 @@ func InitHandler(sandbox Sandbox, functionVersion string, timeout int64) (time.T // pass to rapid sandbox.Init(&interop.Init{ Handler: GetenvWithDefault("AWS_LAMBDA_FUNCTION_HANDLER", os.Getenv("_HANDLER")), - CorrelationID: "initCorrelationID", + CorrelationID: "initCorrelationID", // TODO AwsKey: os.Getenv("AWS_ACCESS_KEY_ID"), AwsSecret: os.Getenv("AWS_SECRET_ACCESS_KEY"), AwsSession: os.Getenv("AWS_SESSION_TOKEN"), - XRayDaemonAddress: "0.0.0.0:0", // TODO + XRayDaemonAddress: GetenvWithDefault("AWS_XRAY_DAEMON_ADDRESS", "127.0.0.1:2000"), FunctionName: GetenvWithDefault("AWS_LAMBDA_FUNCTION_NAME", "test_function"), FunctionVersion: functionVersion, diff --git a/cmd/localstack/custom_interop.go b/cmd/localstack/custom_interop.go index 5fb07f3..87efcb3 100644 --- a/cmd/localstack/custom_interop.go +++ b/cmd/localstack/custom_interop.go @@ -44,12 +44,14 @@ func (l *LocalStackAdapter) SendStatus(status LocalStackStatus) error { return nil } +// The InvokeRequest is sent by LocalStack to trigger an invocation type InvokeRequest struct { InvokeId string `json:"invoke-id"` InvokedFunctionArn string `json:"invoked-function-arn"` Payload string `json:"payload"` } +// The ErrorResponse is sent TO LocalStack when encountering an error type ErrorResponse struct { ErrorMessage string `json:"errorMessage"` ErrorType string `json:"errorType,omitempty"` @@ -95,10 +97,9 @@ func NewCustomInteropServer(lsOpts *LsOpts, delegate rapidcore.InteropServer, lo Payload: strings.NewReader(invokeR.Payload), // r.Body, NeedDebugLogs: true, CorrelationID: "invokeCorrelationID", - // TODO: should we use the env _X_AMZN_TRACE_ID here or get the value from the request headers from the direct invoke? - // for now we just set a "real" static value - TraceID: "Root=1-53cfd31b-192638fa13e39d2c2bcea001;Parent=365fb4b15f2e3987;Sampled=0", // r.Header.Get("X-Amzn-Trace-Id"), - //TraceID: GetEnvOrDie("_X_AMZN_TRACE_ID"), // r.Header.Get("X-Amzn-Trace-Id"), + + // TODO: unclear how this would behave for non-managed runtimes + TraceID: GetEnvOrDie("_X_AMZN_TRACE_ID"), // r.Header.Get("X-Amzn-Trace-Id"), // TODO: set correct segment ID from request //LambdaSegmentID: "LambdaSegmentID", // r.Header.Get("X-Amzn-Segment-Id"), //CognitoIdentityID: "", diff --git a/cmd/localstack/main.go b/cmd/localstack/main.go index f2e0195..961c9ac 100644 --- a/cmd/localstack/main.go +++ b/cmd/localstack/main.go @@ -24,6 +24,7 @@ type LsOpts struct { HotReloadingPaths []string EnableDnsServer string LocalstackIP string + InitLogLevel string } func GetEnvOrDie(env string) string { @@ -36,12 +37,14 @@ func GetEnvOrDie(env string) string { func InitLsOpts() *LsOpts { return &LsOpts{ + // required RuntimeEndpoint: GetEnvOrDie("LOCALSTACK_RUNTIME_ENDPOINT"), RuntimeId: GetEnvOrDie("LOCALSTACK_RUNTIME_ID"), // optional with default InteropPort: GetenvWithDefault("LOCALSTACK_INTEROP_PORT", "9563"), InitTracingPort: GetenvWithDefault("LOCALSTACK_RUNTIME_TRACING_PORT", "9564"), User: GetenvWithDefault("LOCALSTACK_USER", "sbx_user1051"), + InitLogLevel: GetenvWithDefault("LOCALSTACK_INIT_LOG_LEVEL", "debug"), // optional or empty CodeArchives: os.Getenv("LOCALSTACK_CODE_ARCHIVES"), HotReloadingPaths: strings.Split(GetenvWithDefault("LOCALSTACK_HOT_RELOADING_PATHS", ""), ","), @@ -78,22 +81,33 @@ func main() { // we're setting this to the same value as in the official RIE debug.SetGCPercent(33) + // configuration parsing lsOpts := InitLsOpts() UnsetLsEnvs() - // set up logging (logrus) - //log.SetFormatter(&log.JSONFormatter{}) - //log.SetLevel(log.TraceLevel) - log.SetLevel(log.DebugLevel) + // set up logging log.SetReportCaller(true) + switch lsOpts.InitLogLevel { + case "debug": + log.SetLevel(log.DebugLevel) + case "trace": + log.SetFormatter(&log.JSONFormatter{}) + log.SetLevel(log.TraceLevel) + default: + log.Fatal("Invalid value for LOCALSTACK_INIT_LOG_LEVEL") + } + + // enable dns server + dnsServerContext, stopDnsServer := context.WithCancel(context.Background()) + go RunDNSRewriter(lsOpts, dnsServerContext) // download code archive if env variable is set if err := DownloadCodeArchives(lsOpts.CodeArchives); err != nil { log.Fatal("Failed to download code archives") } - // enable dns server - dnsServerContext, stopDnsServer := context.WithCancel(context.Background()) - go RunDNSRewriter(lsOpts, dnsServerContext) + + // parse CLI args + bootstrap, handler := getBootstrap(os.Args) // Switch to non-root user and drop root privileges if IsRootUser() && lsOpts.User != "" { @@ -108,23 +122,40 @@ func main() { UserLogger().Debugln("Process running as non-root user.") } - // parse CLI args - opts, args := getCLIArgs() - bootstrap, handler := getBootstrap(args, opts) logCollector := NewLogCollector() + + // file watcher for hot-reloading fileWatcherContext, cancelFileWatcher := context.WithCancel(context.Background()) + + // build sandbox sandbox := rapidcore. NewSandboxBuilder(bootstrap). + //SetTracer(tracer). AddShutdownFunc(func() { - log.Debugln("Closing contexts") + log.Debugln("Stopping file watcher") cancelFileWatcher() + log.Debugln("Stopping DNS server") stopDnsServer() }). - AddShutdownFunc(func() { os.Exit(0) }). SetExtensionsFlag(true). SetInitCachingFlag(true). SetTailLogOutput(logCollector) + // xray daemon + if shouldRunXrayDaemon() { + xrayConfig := initConfig( + "http://"+lsOpts.LocalstackIP+":4566", + GetEnvOrDie("LOCALSTACK_LAMBDA_FUNCTION_ARN"), + ) + d := initDaemon(xrayConfig) + sandbox.AddShutdownFunc(func() { + d.stop() + }) + runDaemon(d) // async + + defer d.close() // synchronous wait for all receivers to be finished + } + defaultInterop := sandbox.InteropServer() interopServer := NewCustomInteropServer(lsOpts, defaultInterop, logCollector) sandbox.SetInteropServer(interopServer) @@ -136,7 +167,7 @@ func main() { go sandbox.Create() // get timeout - invokeTimeoutEnv := GetEnvOrDie("AWS_LAMBDA_FUNCTION_TIMEOUT") + invokeTimeoutEnv := GetEnvOrDie("AWS_LAMBDA_FUNCTION_TIMEOUT") // TODO: collect all AWS_* env parsing invokeTimeoutSeconds, err := strconv.Atoi(invokeTimeoutEnv) if err != nil { log.Fatalln(err) @@ -153,3 +184,13 @@ func main() { log.Fatal("Failed to start debug server") } } + +func shouldRunXrayDaemon() bool { + xrayAddress := os.Getenv("AWS_XRAY_DAEMON_ADDRESS") + traceHeaer := os.Getenv("_X_AMZN_TRACE_ID") + if xrayAddress != "" && traceHeaer != "" { + // no point in running the daemon if we don't actually sample the request + return strings.Contains(traceHeaer, "Sampled=1") + } + return false +} diff --git a/cmd/localstack/xraydaemon.go b/cmd/localstack/xraydaemon.go new file mode 100644 index 0000000..1855b22 --- /dev/null +++ b/cmd/localstack/xraydaemon.go @@ -0,0 +1,301 @@ +// The implementation is based on the open source AWS xray daemon https://github.com/aws/aws-xray-daemon (cmd/tracing/daemon.go) +// It has been adapted for the use as a library and not as a separate executable. +// The config is set directly in code instead of loading it from a config file + +package main + +import ( + "encoding/json" + "io" + "math" + "net" + "os" + "sync/atomic" + "time" + + "github.com/aws/aws-xray-daemon/pkg/bufferpool" + "github.com/aws/aws-xray-daemon/pkg/cfg" + "github.com/aws/aws-xray-daemon/pkg/conn" + "github.com/aws/aws-xray-daemon/pkg/logger" + "github.com/aws/aws-xray-daemon/pkg/processor" + "github.com/aws/aws-xray-daemon/pkg/proxy" + "github.com/aws/aws-xray-daemon/pkg/ringbuffer" + "github.com/aws/aws-xray-daemon/pkg/socketconn" + "github.com/aws/aws-xray-daemon/pkg/socketconn/udp" + "github.com/aws/aws-xray-daemon/pkg/telemetry" + "github.com/aws/aws-xray-daemon/pkg/tracesegment" + "github.com/aws/aws-xray-daemon/pkg/util" + + "github.com/aws/aws-sdk-go/aws" + log "github.com/cihub/seelog" + "github.com/shirou/gopsutil/mem" +) + +const protocolSeparator = "\n" + +// Log Rotation Size is 50 MB +const logRotationSize int64 = 50 * 1024 * 1024 + +var noMetadata = true + +var logFile string +var logLevel string + +// Daemon reads trace segments from X-Ray daemon address and +// send to X-Ray service. +type Daemon struct { + receiverCount int + processorCount int + receiveBufferSize int + + // Boolean channel, set to true if error is received reading from Socket. + done chan bool + + // Ring buffer, used to stored segments received. + std *ringbuffer.RingBuffer + + // Counter for segments read by daemon. + count uint64 + + // Instance of socket connection. + sock socketconn.SocketConn + + // Reference to buffer pool. + pool *bufferpool.BufferPool + + // Reference to Processor. + processor *processor.Processor + + // HTTP Proxy server + server *proxy.Server +} + +func initConfig(endpoint, resourceArn string) *cfg.Config { + xrayConfig := cfg.DefaultConfig() + xrayConfig.Socket.UDPAddress = "0.0.0.0:2000" + xrayConfig.Socket.TCPAddress = "0.0.0.0:2000" + xrayConfig.Endpoint = endpoint + xrayConfig.NoVerifySSL = util.Bool(true) // obvious + xrayConfig.LocalMode = util.Bool(true) // skip EC2 metadata check + xrayConfig.ResourceARN = resourceArn + xrayConfig.Region = GetEnvOrDie("AWS_REGION") + xrayConfig.Logging.LogLevel = "dev" // TODO + //xrayConfig.TotalBufferSizeMB + //xrayConfig.RoleARN = roleARN + + return xrayConfig +} + +func initDaemon(config *cfg.Config) *Daemon { + if logFile != "" { + var fileWriter io.Writer + if *config.Logging.LogRotation { + // Empty Archive path as code does not archive logs + apath := "" + maxSize := logRotationSize + // Keep one rolled over log file around + maxRolls := 1 + archiveExplode := false + fileWriter, _ = log.NewRollingFileWriterSize(logFile, 0, apath, maxSize, maxRolls, 0, archiveExplode) + } else { + fileWriter, _ = log.NewFileWriter(logFile) + } + logger.LoadLogConfig(fileWriter, config, logLevel) + } else { + newWriter, _ := log.NewConsoleWriter() + logger.LoadLogConfig(newWriter, config, logLevel) + } + defer log.Flush() + + log.Infof("Initializing AWS X-Ray daemon %v", cfg.Version) + + parameterConfig := cfg.ParameterConfigValue + parameterConfig.Processor.BatchSize = 2 + parameterConfig.Processor.IdleTimeoutMillisecond = 30_000 + receiveBufferSize := parameterConfig.Socket.BufferSizeKB * 1024 + + var sock socketconn.SocketConn + + sock = udp.New(config.Socket.UDPAddress) + + memoryLimit := evaluateBufferMemory(0) + log.Infof("Using buffer memory limit of %v MB", memoryLimit) + buffers, err := bufferpool.GetPoolBufferCount(memoryLimit, receiveBufferSize) + if err != nil { + log.Errorf("%v", err) + os.Exit(1) + } + log.Infof("%v segment buffers allocated", buffers) + bufferPool := bufferpool.Init(buffers, receiveBufferSize) + std := ringbuffer.New(buffers, bufferPool) + if config.Endpoint != "" { + log.Debugf("Using Endpoint read from Config file: %s", config.Endpoint) + } + awsConfig, session := conn.GetAWSConfigSession(&conn.Conn{}, config, config.RoleARN, config.Region, noMetadata) + log.Infof("Using region: %v", aws.StringValue(awsConfig.Region)) + + log.Debugf("ARN of the AWS resource running the daemon: %v", config.ResourceARN) + telemetry.Init(awsConfig, session, config.ResourceARN, noMetadata) + + // If calculated number of buffer is lower than our default, use calculated one. Otherwise, use default value. + parameterConfig.Processor.BatchSize = util.GetMinIntValue(parameterConfig.Processor.BatchSize, buffers) + + // Create proxy http server + server, err := proxy.NewServer(config, awsConfig, session) + if err != nil { + log.Errorf("Unable to start http proxy server: %v", err) + os.Exit(1) + } + processorCount := 2 + + daemon := &Daemon{ + receiverCount: parameterConfig.ReceiverRoutines, + processorCount: processorCount, + receiveBufferSize: receiveBufferSize, + done: make(chan bool), + std: std, + pool: bufferPool, + count: 0, + sock: sock, + server: server, + processor: processor.New(awsConfig, session, processorCount, std, bufferPool, parameterConfig), + } + + return daemon +} + +func runDaemon(daemon *Daemon) { + // Start http server for proxying requests to xray + go daemon.server.Serve() + + for i := 0; i < daemon.receiverCount; i++ { + go daemon.poll() + } +} + +func (d *Daemon) close() { + for i := 0; i < d.receiverCount; i++ { + <-d.done + } + // Signal routines to finish + // This will push telemetry and customer segments in parallel + d.std.Close() + telemetry.T.Quit <- true + + <-d.processor.Done + <-telemetry.T.Done + + log.Debugf("Trace segment: received: %d, truncated: %d, processed: %d", atomic.LoadUint64(&d.count), d.std.TruncatedCount(), d.processor.ProcessedCount()) + log.Debugf("Shutdown finished. Current epoch in nanoseconds: %v", time.Now().UnixNano()) +} + +func (d *Daemon) stop() { + d.sock.Close() + d.server.Close() +} + +// Returns number of bytes read from socket connection. +func (d *Daemon) read(buf *[]byte) int { + bufVal := *buf + rlen, err := d.sock.Read(bufVal) + switch err := err.(type) { + case net.Error: + if !err.Temporary() { + d.done <- true + return -1 + } + log.Errorf("daemon: net: err: %v", err) + return 0 + case error: + log.Errorf("daemon: socket: err: %v", err) + return 0 + } + return rlen +} + +func (d *Daemon) poll() { + separator := []byte(protocolSeparator) + fallBackBuffer := make([]byte, d.receiveBufferSize) + splitBuf := make([][]byte, 2) + + for { + bufPointer := d.pool.Get() + fallbackPointerUsed := false + if bufPointer == nil { + log.Debug("Pool does not have any buffer.") + bufPointer = &fallBackBuffer + fallbackPointerUsed = true + } + rlen := d.read(bufPointer) + if rlen > 0 { + telemetry.T.SegmentReceived(1) + } + if rlen == 0 { + if !fallbackPointerUsed { + d.pool.Return(bufPointer) + } + continue + } + if fallbackPointerUsed { + log.Warn("Segment dropped. Consider increasing memory limit") + telemetry.T.SegmentSpillover(1) + continue + } else if rlen == -1 { + return + } + + buf := *bufPointer + bufMessage := buf[0:rlen] + + slices := util.SplitHeaderBody(&bufMessage, &separator, &splitBuf) + if len(slices[1]) == 0 { + log.Warnf("Missing header or segment: %s", string(slices[0])) + d.pool.Return(bufPointer) + telemetry.T.SegmentRejected(1) + continue + } + + header := slices[0] + payload := slices[1] + headerInfo := tracesegment.Header{} + json.Unmarshal(header, &headerInfo) + + switch headerInfo.IsValid() { + case true: + default: + log.Warnf("Invalid header: %s", string(header)) + d.pool.Return(bufPointer) + telemetry.T.SegmentRejected(1) + continue + } + + ts := &tracesegment.TraceSegment{ + Raw: &payload, + PoolBuf: bufPointer, + } + + atomic.AddUint64(&d.count, 1) + d.std.Send(ts) + } +} + +func evaluateBufferMemory(cliBufferMemory int) int { + var bufferMemoryMB int + if cliBufferMemory > 0 { + bufferMemoryMB = cliBufferMemory + } else { + vm, err := mem.VirtualMemory() + if err != nil { + log.Errorf("%v", err) + os.Exit(1) + } + bufferMemoryLimitPercentageOfTotal := 0.01 + totalBytes := vm.Total + bufferMemoryMB = int(math.Floor(bufferMemoryLimitPercentageOfTotal * float64(totalBytes) / float64(1024*1024))) + } + if bufferMemoryMB < 3 { + log.Error("Not enough Buffers Memory Allocated. Min Buffers Memory required: 3 MB.") + os.Exit(1) + } + return bufferMemoryMB +} diff --git a/custom-tests/build-delve/build.sh b/custom-tests/build-delve/build.sh deleted file mode 100755 index 69f6a2b..0000000 --- a/custom-tests/build-delve/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -mkdir -p /tmp/build-delve -cd /tmp/build-delve -git clone https://github.com/go-delve/delve.git -cd delve -make build -mv dlv /app/dlv \ No newline at end of file diff --git a/custom-tests/init/var/rapid/entrypoint.sh b/custom-tests/init/var/rapid/entrypoint.sh deleted file mode 100755 index 2819c9a..0000000 --- a/custom-tests/init/var/rapid/entrypoint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -LAMBDA_INIT_DELVE_PORT="${LAMBDA_INIT_DELVE_PORT:-40000}" - -exec /var/rapid/dlv --listen=:${LAMBDA_INIT_DELVE_PORT} --headless=true --api-version=2 --accept-multiclient exec /var/rapid/init \ No newline at end of file diff --git a/debugging/init/var/rapid/entrypoint.sh b/debugging/init/var/rapid/entrypoint.sh index c0c01cd..2e49d62 100755 --- a/debugging/init/var/rapid/entrypoint.sh +++ b/debugging/init/var/rapid/entrypoint.sh @@ -5,4 +5,5 @@ LAMBDA_INIT_DELVE_PORT="${LAMBDA_INIT_DELVE_PORT:-40000}" # Run init without delve debugger #exec /var/rapid/init +# Run init with delve debugger exec /var/rapid/dlv --listen=:${LAMBDA_INIT_DELVE_PORT} --headless=true --api-version=2 --accept-multiclient exec /var/rapid/init diff --git a/go.mod b/go.mod index 68fda7f..cbdaeee 100644 --- a/go.mod +++ b/go.mod @@ -4,26 +4,34 @@ go 1.18 require ( github.com/aws/aws-lambda-go v1.20.0 + github.com/aws/aws-sdk-go v1.44.62 + github.com/aws/aws-xray-daemon v0.0.0-20230202010956-acaf06e9a638 + github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 github.com/fsnotify/fsnotify v1.6.0 github.com/go-chi/chi v4.1.2+incompatible github.com/go-chi/render v1.0.1 github.com/google/uuid v1.1.2 github.com/jessevdk/go-flags v1.4.0 github.com/miekg/dns v1.1.50 + github.com/shirou/gopsutil v2.19.10+incompatible github.com/sirupsen/logrus v1.6.0 github.com/stretchr/testify v1.6.1 - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c + golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 golang.org/x/sys v0.1.0 ) require ( + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-ole/go-ole v1.2.4 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/objx v0.1.0 // indirect - golang.org/x/mod v0.4.2 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.1.0 // indirect - golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + golang.org/x/text v0.4.0 // indirect + golang.org/x/tools v0.1.12 // indirect + gopkg.in/yaml.v2 v2.2.8 // indirect gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect ) diff --git a/go.sum b/go.sum index 8d30ee9..60f49db 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,14 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/aws/aws-lambda-go v1.20.0 h1:ZSweJx/Hy9BoIDXKBEh16vbHH0t0dehnF8MKpMiOWc0= github.com/aws/aws-lambda-go v1.20.0/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU= +github.com/aws/aws-sdk-go v1.44.62 h1:N8qOPnBhl2ZCIFiqyB640Xt5CeX9D8CEVhG/Vj7jGJU= +github.com/aws/aws-sdk-go v1.44.62/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-xray-daemon v0.0.0-20230202010956-acaf06e9a638 h1:G0C87W0m2uyh3uHV24Q60JJx+AyJ3//gJjalvSizXhc= +github.com/aws/aws-xray-daemon v0.0.0-20230202010956-acaf06e9a638/go.mod h1:glwf7zqf0NzGozJscRs0/xC+CpTU4DyMN4V9eXxD2Co= +github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs= +github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -12,17 +20,26 @@ github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyN github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8= github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns= +github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v2.19.10+incompatible h1:lA4Pi29JEVIQIgATSeftHSY0rMGI9CLrl2ZvDLiahto= +github.com/shirou/gopsutil v2.19.10+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= @@ -35,17 +52,20 @@ github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -53,26 +73,33 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 44ba29b58d6b37902eb7c2200d82f5b9d8dde34e Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Fri, 17 Mar 2023 14:47:30 +0100 Subject: [PATCH 3/6] misc fixes --- cmd/localstack/custom_interop.go | 4 ++-- cmd/localstack/main.go | 33 ++++++++++---------------------- cmd/localstack/xraydaemon.go | 7 +++---- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/cmd/localstack/custom_interop.go b/cmd/localstack/custom_interop.go index 87efcb3..35831fa 100644 --- a/cmd/localstack/custom_interop.go +++ b/cmd/localstack/custom_interop.go @@ -49,6 +49,7 @@ type InvokeRequest struct { InvokeId string `json:"invoke-id"` InvokedFunctionArn string `json:"invoked-function-arn"` Payload string `json:"payload"` + TraceId string `json:"trace-id"` } // The ErrorResponse is sent TO LocalStack when encountering an error @@ -98,8 +99,7 @@ func NewCustomInteropServer(lsOpts *LsOpts, delegate rapidcore.InteropServer, lo NeedDebugLogs: true, CorrelationID: "invokeCorrelationID", - // TODO: unclear how this would behave for non-managed runtimes - TraceID: GetEnvOrDie("_X_AMZN_TRACE_ID"), // r.Header.Get("X-Amzn-Trace-Id"), + TraceID: invokeR.TraceId, // TODO: set correct segment ID from request //LambdaSegmentID: "LambdaSegmentID", // r.Header.Get("X-Amzn-Segment-Id"), //CognitoIdentityID: "", diff --git a/cmd/localstack/main.go b/cmd/localstack/main.go index 961c9ac..4063c61 100644 --- a/cmd/localstack/main.go +++ b/cmd/localstack/main.go @@ -25,6 +25,7 @@ type LsOpts struct { EnableDnsServer string LocalstackIP string InitLogLevel string + EdgePort string } func GetEnvOrDie(env string) string { @@ -45,6 +46,7 @@ func InitLsOpts() *LsOpts { InitTracingPort: GetenvWithDefault("LOCALSTACK_RUNTIME_TRACING_PORT", "9564"), User: GetenvWithDefault("LOCALSTACK_USER", "sbx_user1051"), InitLogLevel: GetenvWithDefault("LOCALSTACK_INIT_LOG_LEVEL", "debug"), + EdgePort: GetenvWithDefault("EDGE_PORT", "4566"), // optional or empty CodeArchives: os.Getenv("LOCALSTACK_CODE_ARCHIVES"), HotReloadingPaths: strings.Split(GetenvWithDefault("LOCALSTACK_HOT_RELOADING_PATHS", ""), ","), @@ -65,6 +67,7 @@ func UnsetLsEnvs() { "LOCALSTACK_CODE_ARCHIVES", "LOCALSTACK_HOT_RELOADING_PATHS", "LOCALSTACK_ENABLE_DNS_SERVER", + "LOCALSTACK_INIT_LOG_LEVEL", // Docker container ID "HOSTNAME", // User @@ -142,19 +145,13 @@ func main() { SetTailLogOutput(logCollector) // xray daemon - if shouldRunXrayDaemon() { - xrayConfig := initConfig( - "http://"+lsOpts.LocalstackIP+":4566", - GetEnvOrDie("LOCALSTACK_LAMBDA_FUNCTION_ARN"), - ) - d := initDaemon(xrayConfig) - sandbox.AddShutdownFunc(func() { - d.stop() - }) - runDaemon(d) // async - - defer d.close() // synchronous wait for all receivers to be finished - } + xrayConfig := initConfig("http://" + lsOpts.LocalstackIP + ":" + lsOpts.EdgePort) + d := initDaemon(xrayConfig) + sandbox.AddShutdownFunc(func() { + d.stop() + }) + runDaemon(d) // async + defer d.close() // synchronous wait for all receivers to be finished defaultInterop := sandbox.InteropServer() interopServer := NewCustomInteropServer(lsOpts, defaultInterop, logCollector) @@ -184,13 +181,3 @@ func main() { log.Fatal("Failed to start debug server") } } - -func shouldRunXrayDaemon() bool { - xrayAddress := os.Getenv("AWS_XRAY_DAEMON_ADDRESS") - traceHeaer := os.Getenv("_X_AMZN_TRACE_ID") - if xrayAddress != "" && traceHeaer != "" { - // no point in running the daemon if we don't actually sample the request - return strings.Contains(traceHeaer, "Sampled=1") - } - return false -} diff --git a/cmd/localstack/xraydaemon.go b/cmd/localstack/xraydaemon.go index 1855b22..6356968 100644 --- a/cmd/localstack/xraydaemon.go +++ b/cmd/localstack/xraydaemon.go @@ -70,14 +70,13 @@ type Daemon struct { server *proxy.Server } -func initConfig(endpoint, resourceArn string) *cfg.Config { +func initConfig(endpoint string) *cfg.Config { xrayConfig := cfg.DefaultConfig() xrayConfig.Socket.UDPAddress = "0.0.0.0:2000" xrayConfig.Socket.TCPAddress = "0.0.0.0:2000" xrayConfig.Endpoint = endpoint xrayConfig.NoVerifySSL = util.Bool(true) // obvious xrayConfig.LocalMode = util.Bool(true) // skip EC2 metadata check - xrayConfig.ResourceARN = resourceArn xrayConfig.Region = GetEnvOrDie("AWS_REGION") xrayConfig.Logging.LogLevel = "dev" // TODO //xrayConfig.TotalBufferSizeMB @@ -110,7 +109,7 @@ func initDaemon(config *cfg.Config) *Daemon { log.Infof("Initializing AWS X-Ray daemon %v", cfg.Version) parameterConfig := cfg.ParameterConfigValue - parameterConfig.Processor.BatchSize = 2 + parameterConfig.Processor.BatchSize = 2 // TODO parameterConfig.Processor.IdleTimeoutMillisecond = 30_000 receiveBufferSize := parameterConfig.Socket.BufferSizeKB * 1024 @@ -146,7 +145,7 @@ func initDaemon(config *cfg.Config) *Daemon { log.Errorf("Unable to start http proxy server: %v", err) os.Exit(1) } - processorCount := 2 + processorCount := 2 // TODO daemon := &Daemon{ receiverCount: parameterConfig.ReceiverRoutines, From 9c7f7cce6dba87146552f6e33aca68a2b1eccff4 Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Fri, 17 Mar 2023 14:53:32 +0100 Subject: [PATCH 4/6] bind to localhost --- cmd/localstack/xraydaemon.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/localstack/xraydaemon.go b/cmd/localstack/xraydaemon.go index 6356968..69a55aa 100644 --- a/cmd/localstack/xraydaemon.go +++ b/cmd/localstack/xraydaemon.go @@ -72,8 +72,8 @@ type Daemon struct { func initConfig(endpoint string) *cfg.Config { xrayConfig := cfg.DefaultConfig() - xrayConfig.Socket.UDPAddress = "0.0.0.0:2000" - xrayConfig.Socket.TCPAddress = "0.0.0.0:2000" + xrayConfig.Socket.UDPAddress = "127.0.0.1:2000" + xrayConfig.Socket.TCPAddress = "127.0.0.1:2000" xrayConfig.Endpoint = endpoint xrayConfig.NoVerifySSL = util.Bool(true) // obvious xrayConfig.LocalMode = util.Bool(true) // skip EC2 metadata check @@ -109,7 +109,7 @@ func initDaemon(config *cfg.Config) *Daemon { log.Infof("Initializing AWS X-Ray daemon %v", cfg.Version) parameterConfig := cfg.ParameterConfigValue - parameterConfig.Processor.BatchSize = 2 // TODO + parameterConfig.Processor.BatchSize = 4 parameterConfig.Processor.IdleTimeoutMillisecond = 30_000 receiveBufferSize := parameterConfig.Socket.BufferSizeKB * 1024 @@ -145,7 +145,7 @@ func initDaemon(config *cfg.Config) *Daemon { log.Errorf("Unable to start http proxy server: %v", err) os.Exit(1) } - processorCount := 2 // TODO + processorCount := 2 daemon := &Daemon{ receiverCount: parameterConfig.ReceiverRoutines, From 0c12c424fe9796d48f542b002ba0a20a9110dec2 Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Fri, 17 Mar 2023 15:38:24 +0100 Subject: [PATCH 5/6] reduce flush interval --- cmd/localstack/main.go | 6 ++++-- cmd/localstack/xraydaemon.go | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/localstack/main.go b/cmd/localstack/main.go index 4063c61..8a4187a 100644 --- a/cmd/localstack/main.go +++ b/cmd/localstack/main.go @@ -148,10 +148,12 @@ func main() { xrayConfig := initConfig("http://" + lsOpts.LocalstackIP + ":" + lsOpts.EdgePort) d := initDaemon(xrayConfig) sandbox.AddShutdownFunc(func() { + log.Debugln("Shutting down xray daemon") d.stop() + log.Debugln("Flushing segments in xray daemon") + d.close() }) - runDaemon(d) // async - defer d.close() // synchronous wait for all receivers to be finished + runDaemon(d) // async defaultInterop := sandbox.InteropServer() interopServer := NewCustomInteropServer(lsOpts, defaultInterop, logCollector) diff --git a/cmd/localstack/xraydaemon.go b/cmd/localstack/xraydaemon.go index 69a55aa..b6570dd 100644 --- a/cmd/localstack/xraydaemon.go +++ b/cmd/localstack/xraydaemon.go @@ -109,8 +109,8 @@ func initDaemon(config *cfg.Config) *Daemon { log.Infof("Initializing AWS X-Ray daemon %v", cfg.Version) parameterConfig := cfg.ParameterConfigValue - parameterConfig.Processor.BatchSize = 4 - parameterConfig.Processor.IdleTimeoutMillisecond = 30_000 + parameterConfig.Processor.BatchSize = 10 + parameterConfig.Processor.IdleTimeoutMillisecond = 1000 receiveBufferSize := parameterConfig.Socket.BufferSizeKB * 1024 var sock socketconn.SocketConn From 3fc0a5535974806db8a5c9554cf1de92d5d7348e Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Tue, 21 Mar 2023 08:46:04 +0100 Subject: [PATCH 6/6] fix pr issues --- cmd/localstack/awsutil.go | 2 +- cmd/localstack/xraydaemon.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/localstack/awsutil.go b/cmd/localstack/awsutil.go index 529bb99..b28d734 100644 --- a/cmd/localstack/awsutil.go +++ b/cmd/localstack/awsutil.go @@ -130,7 +130,7 @@ func resetListener(changeChannel <-chan bool, server *CustomInteropServer) { func RunDNSRewriter(opts *LsOpts, ctx context.Context) { if opts.EnableDnsServer != "1" { - log.Debugln("DNS server disabled. S") + log.Debugln("DNS server disabled.") return } dnsForwarder, err := NewDnsForwarder(opts.LocalstackIP) diff --git a/cmd/localstack/xraydaemon.go b/cmd/localstack/xraydaemon.go index b6570dd..8d2b768 100644 --- a/cmd/localstack/xraydaemon.go +++ b/cmd/localstack/xraydaemon.go @@ -78,7 +78,7 @@ func initConfig(endpoint string) *cfg.Config { xrayConfig.NoVerifySSL = util.Bool(true) // obvious xrayConfig.LocalMode = util.Bool(true) // skip EC2 metadata check xrayConfig.Region = GetEnvOrDie("AWS_REGION") - xrayConfig.Logging.LogLevel = "dev" // TODO + xrayConfig.Logging.LogLevel = "info" //xrayConfig.TotalBufferSizeMB //xrayConfig.RoleARN = roleARN