From e0e89bc6221826b3ac67bfacca35b0f6a19c2d9a Mon Sep 17 00:00:00 2001 From: Darragh O'Reilly Date: Wed, 26 Jun 2024 14:34:34 +0100 Subject: [PATCH] Allow sysadmins to see what is being collected This allows system admins to see what is being collected on their endpoints. It can be enabled by creating a directory named `uploads` in the same directory as the `local_buffer` file. If this directory exists then events that are uploaded to the server server will also be appended to a daily json file within it. There is no auto removal of old files so admins will have to manage that themselves. It can be disabled again by simply removing the `uploads` directory. --- http_comms/sender.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/http_comms/sender.go b/http_comms/sender.go index ef35b2369..29201b342 100644 --- a/http_comms/sender.go +++ b/http_comms/sender.go @@ -26,6 +26,8 @@ package http_comms import ( "context" + "os" + "path/filepath" "sync" "sync/atomic" "time" @@ -121,6 +123,9 @@ func (self *Sender) PumpExecutorToRingBuffer(ctx context.Context) { self.urgent_buffer.Enqueue(serialized_msg) } else { + if msg.VQLResponse != nil { + self.LogResponse(msg.VQLResponse.JSONLResponse) + } // NOTE: This is kind of a hack. We hold in // memory a bunch of VeloMessage proto objects // and we want to serialize them into a @@ -167,6 +172,38 @@ func (self *Sender) PumpExecutorToRingBuffer(ctx context.Context) { } } +// LogResponse logs the results of VQL queries to a daily json file. +// Administrators who want to see what is being collected on their +// endpoints can enable this by creating a directory named "uploads" +// in the same directory as the local_buffer file. +func (self *Sender) LogResponse(response string) { + ringBufferDir := filepath.Dir(getLocalBufferName(self.config_obj)) + uploadsDir := filepath.Join(ringBufferDir, "uploads") + _, err := os.Stat(uploadsDir) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return + } + self.logger.Debug("LogResponse stat: %s", err) + return + } + + name := time.Now().Format("2006-01-02") + ".json" + path := filepath.Join(uploadsDir, name) + f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.FileMode(0600)) + if err != nil { + self.logger.Debug("LogResponse open: %v", err) + return + } + defer f.Close() + + _, err = f.WriteString(response) + if err != nil { + self.logger.Debug("LogResponse write: %v", err) + return + } +} + // Manages the sending of messages to the server. Reads messages from // the ring buffer if there are any to send and compose a Message List // to send. This also manages timing and retransmissions - blocks if