From 0afe8a068764875ef46453b95a72baa97399a5ff Mon Sep 17 00:00:00 2001 From: Martijn van Schaardenburg Date: Tue, 7 Nov 2023 18:38:08 +0000 Subject: [PATCH 1/5] Testing: Use simpler logger types --- integration_test/gce/gce_testing.go | 12 +- integration_test/ops_agent_test.go | 516 +++++++++++----------- integration_test/third_party_apps_test.go | 40 +- 3 files changed, 292 insertions(+), 276 deletions(-) diff --git a/integration_test/gce/gce_testing.go b/integration_test/gce/gce_testing.go index abdfe5df1e..e36b2e0135 100644 --- a/integration_test/gce/gce_testing.go +++ b/integration_test/gce/gce_testing.go @@ -833,7 +833,9 @@ func RunRemotely(ctx context.Context, logger *log.Logger, vm *VM, stdin string, // a "Storage Object Viewer" and "Storage Object Creator" on the bucket. func UploadContent(ctx context.Context, logger *log.Logger, vm *VM, content io.Reader, remotePath string) (err error) { defer func() { - logger.Printf("Uploading file finished with err=%v", err) + if err != nil { + logger.Printf("Uploading file finished with err=%v", err) + } }() object := storageClient.Bucket(transfersBucket).Object(path.Join(vm.Name, remotePath)) writer := object.NewWriter(ctx) @@ -902,7 +904,7 @@ func envVarMapToPowershellPrefix(env map[string]string) string { // $ErrorActionPreference = 'Stop' // This will cause a broader class of errors to be reported as an error (nonzero exit code) // by powershell. -func RunScriptRemotely(ctx context.Context, logger *logging.DirectoryLogger, vm *VM, scriptContents string, flags []string, env map[string]string) (CommandOutput, error) { +func RunScriptRemotely(ctx context.Context, logger *log.Logger, vm *VM, scriptContents string, flags []string, env map[string]string) (CommandOutput, error) { var quotedFlags []string for _, flag := range flags { quotedFlags = append(quotedFlags, fmt.Sprintf("'%s'", flag)) @@ -913,21 +915,21 @@ func RunScriptRemotely(ctx context.Context, logger *logging.DirectoryLogger, vm // Use a UUID for the script name in case RunScriptRemotely is being // called concurrently on the same VM. scriptPath := "C:\\" + uuid.NewString() + ".ps1" - if err := UploadContent(ctx, logger.ToFile("file_uploads.txt"), vm, strings.NewReader(scriptContents), scriptPath); err != nil { + if err := UploadContent(ctx, logger, vm, strings.NewReader(scriptContents), scriptPath); err != nil { return CommandOutput{}, err } // powershell -File seems to drop certain kinds of errors: // https://stackoverflow.com/a/15779295 // In testing, adding $ErrorActionPreference = 'Stop' to the start of each // script seems to work around this completely. - return RunRemotely(ctx, logger.ToMainLog(), vm, "", envVarMapToPowershellPrefix(env)+"powershell -File "+scriptPath+" "+flagsStr) + return RunRemotely(ctx, logger, vm, "", envVarMapToPowershellPrefix(env)+"powershell -File "+scriptPath+" "+flagsStr) } scriptPath := uuid.NewString() + ".sh" // Write the script contents to .sh, then tell bash to execute it with -x // to print each line as it runs. // Use a UUID for the script name in case RunScriptRemotely is being called // concurrently on the same VM. - return RunRemotely(ctx, logger.ToMainLog(), vm, scriptContents, "cat - > "+scriptPath+" && sudo "+envVarMapToBashPrefix(env)+"bash -x "+scriptPath+" "+flagsStr) + return RunRemotely(ctx, logger, vm, scriptContents, "cat - > "+scriptPath+" && sudo "+envVarMapToBashPrefix(env)+"bash -x "+scriptPath+" "+flagsStr) } // MapToCommaSeparatedList converts a map of key-value pairs into a form that diff --git a/integration_test/ops_agent_test.go b/integration_test/ops_agent_test.go index 5de2ced4b3..ca13c1e7c2 100644 --- a/integration_test/ops_agent_test.go +++ b/integration_test/ops_agent_test.go @@ -67,7 +67,6 @@ import ( "github.com/GoogleCloudPlatform/ops-agent/integration_test/agents" feature_tracking_metadata "github.com/GoogleCloudPlatform/ops-agent/integration_test/feature_tracking" "github.com/GoogleCloudPlatform/ops-agent/integration_test/gce" - "github.com/GoogleCloudPlatform/ops-agent/integration_test/logging" "github.com/GoogleCloudPlatform/ops-agent/integration_test/metadata" "github.com/google/uuid" "go.uber.org/multierr" @@ -151,14 +150,14 @@ func diagnosticsProcessNamesForPlatform(platform string) []string { return []string{"google_cloud_ops_agent_diagnostics"} } -func makeDirectory(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, directory string) error { +func makeDirectory(ctx context.Context, logger *log.Logger, vm *gce.VM, directory string) error { var createFolderCmd string if gce.IsWindows(vm.Platform) { createFolderCmd = fmt.Sprintf("New-Item -ItemType Directory -Path %s", directory) } else { createFolderCmd = fmt.Sprintf("mkdir -p %s", directory) } - _, err := gce.RunScriptRemotely(ctx, logger, vm, createFolderCmd, nil, nil) + _, err := gce.RunRemotely(ctx, logger, vm, "", createFolderCmd) return err } @@ -189,6 +188,18 @@ func writeToWindowsEventLogWithSeverity(ctx context.Context, logger *log.Logger, return nil } +// setupMainLogAndVM sets up a VM for testing and returns it, along with a logger +// that writes to a file called main_log.txt. +// This function is just a wrapper for agents.CommonSetup that returns a "plain" +// log.Logger instead so that the callsite doesn't need to write +// logger.ToMainLog() throughout. +// If you need to write to something besides the main log, just call +// agents.CommonSetup instead. +func setupMainLogAndVM(t *testing.T, platform string) (context.Context, *log.Logger, *gce.VM) { + ctx, dirLog, vm := agents.CommonSetup(t, platform) + return ctx, dirLog.ToMainLog(), vm +} + // writeToSystemLog writes the given payload to the VM's normal log location. // On Linux this is /var/log/syslog or /var/log/messages, depending on the // distro. @@ -215,7 +226,7 @@ func TestParseMultilineFileJava(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) config := fmt.Sprintf(`logging: receivers: @@ -237,7 +248,7 @@ func TestParseMultilineFileJava(t *testing.T) { processors: [multiline_parser_1]`, logPath) //Below lines comes from 3 java exception stacktraces, thus expect 3 logEntries. - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(`Jul 09, 2015 3:23:29 PM com.google.devtools.search.cloud.feeder.MakeLog: RuntimeException: Run from this message! + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(`Jul 09, 2015 3:23:29 PM com.google.devtools.search.cloud.feeder.MakeLog: RuntimeException: Run from this message! at com.my.app.Object.do$a1(MakeLog.java:50) at java.lang.Thing.call(Thing.java:10) javax.servlet.ServletException: Something bad happened @@ -296,14 +307,14 @@ Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EM t.Fatalf("error writing dummy log lines for Java: %v", err) } - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="Jul 09, 2015 3:23:29 PM com.google.devtools.search.cloud.feeder.MakeLog: RuntimeException: Run from this message!\n at com.my.app.Object.do$a1(MakeLog.java:50)\n at java.lang.Thing.call(Thing.java:10)\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="Jul 09, 2015 3:23:29 PM com.google.devtools.search.cloud.feeder.MakeLog: RuntimeException: Run from this message!\n at com.my.app.Object.do$a1(MakeLog.java:50)\n at java.lang.Thing.call(Thing.java:10)\n"`); err != nil { t.Error(err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="javax.servlet.ServletException: Something bad happened\n at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at com.example.myproject.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at com.example.myproject.OutputBufferFilter.doFilter(OutputBufferFilter.java:33)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)\n at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)\n at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)\n at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)\n at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)\n at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)\n at org.mortbay.jetty.Server.handle(Server.java:326)\n at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)\n at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)\n at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)\n at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)\n at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)\n at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)\n at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)\nCaused by: com.example.myproject.MyProjectServletException\n at com.example.myproject.MyServlet.doPost(MyServlet.java:169)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)\n at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)\n at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:30)\n ... 27 common frames omitted\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="javax.servlet.ServletException: Something bad happened\n at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at com.example.myproject.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at com.example.myproject.OutputBufferFilter.doFilter(OutputBufferFilter.java:33)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)\n at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)\n at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)\n at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)\n at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)\n at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)\n at org.mortbay.jetty.Server.handle(Server.java:326)\n at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)\n at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)\n at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)\n at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)\n at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)\n at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)\n at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)\nCaused by: com.example.myproject.MyProjectServletException\n at com.example.myproject.MyServlet.doPost(MyServlet.java:169)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)\n at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)\n at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:30)\n ... 27 common frames omitted\n"`); err != nil { t.Error(err) } }) @@ -316,7 +327,7 @@ func TestParseMultilineFileJavaPython(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) config := fmt.Sprintf(`logging: receivers: @@ -339,7 +350,7 @@ func TestParseMultilineFileJavaPython(t *testing.T) { processors: [multiline_parser_1]`, logPath) //Below lines comes from 3 java and 3 python exception stacktraces, thus expect 6 logEntries. - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(`Jul 09, 2015 3:23:29 PM com.google.devtools.search.cloud.feeder.MakeLog: RuntimeException: Run from this message! + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(`Jul 09, 2015 3:23:29 PM com.google.devtools.search.cloud.feeder.MakeLog: RuntimeException: Run from this message! at com.my.app.Object.do$a1(MakeLog.java:50) at java.lang.Thing.call(Thing.java:10) Traceback (most recent call last): @@ -430,37 +441,37 @@ TypeError: can only concatenate str (not "int") to str t.Fatalf("error writing dummy log lines for Java + Python: %v", err) } - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } // 1st one is Java - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="Jul 09, 2015 3:23:29 PM com.google.devtools.search.cloud.feeder.MakeLog: RuntimeException: Run from this message!\n at com.my.app.Object.do$a1(MakeLog.java:50)\n at java.lang.Thing.call(Thing.java:10)\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="Jul 09, 2015 3:23:29 PM com.google.devtools.search.cloud.feeder.MakeLog: RuntimeException: Run from this message!\n at com.my.app.Object.do$a1(MakeLog.java:50)\n at java.lang.Thing.call(Thing.java:10)\n"`); err != nil { t.Error(err) } // 2nd Python - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n File \"/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py\", line 1535, in __call__\n rv = self.handle_exception(request, response, e)\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 17, in start\n return get()\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 5, in get\n raise Exception('spam', 'eggs')\nException: ('spam', 'eggs')\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n File \"/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py\", line 1535, in __call__\n rv = self.handle_exception(request, response, e)\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 17, in start\n return get()\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 5, in get\n raise Exception('spam', 'eggs')\nException: ('spam', 'eggs')\n"`); err != nil { t.Error(err) } // 3rd Java - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="javax.servlet.ServletException: Something bad happened\n at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at com.example.myproject.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at com.example.myproject.OutputBufferFilter.doFilter(OutputBufferFilter.java:33)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)\n at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)\n at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)\n at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)\n at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)\n at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)\n at org.mortbay.jetty.Server.handle(Server.java:326)\n at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)\n at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)\n at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)\n at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)\n at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)\n at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)\n at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)\nCaused by: com.example.myproject.MyProjectServletException\n at com.example.myproject.MyServlet.doPost(MyServlet.java:169)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)\n at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)\n at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:30)\n ... 27 common frames omitted\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="javax.servlet.ServletException: Something bad happened\n at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:60)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at com.example.myproject.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at com.example.myproject.OutputBufferFilter.doFilter(OutputBufferFilter.java:33)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)\n at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)\n at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)\n at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)\n at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)\n at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)\n at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)\n at org.mortbay.jetty.Server.handle(Server.java:326)\n at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)\n at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)\n at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)\n at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)\n at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)\n at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)\n at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)\nCaused by: com.example.myproject.MyProjectServletException\n at com.example.myproject.MyServlet.doPost(MyServlet.java:169)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)\n at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)\n at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)\n at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)\n at com.example.myproject.OpenSessionInViewFilter.doFilter(OpenSessionInViewFilter.java:30)\n ... 27 common frames omitted\n"`); err != nil { t.Error(err) } // 4th Java - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="java.lang.RuntimeException: javax.mail.SendFailedException: Invalid Addresses;\n nested exception is:\ncom.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendWithSmtp(AutomaticEmailFacade.java:236)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:285)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.lambda$sendSingleEmail$3(AutomaticEmailFacade.java:254)\n at java.util.Optional.ifPresent(Optional.java:159)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:253)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:249)\n at com.nethunt.crm.api.email.EmailSender.lambda$notifyPerson$0(EmailSender.java:80)\n at com.nethunt.crm.api.util.ManagedExecutor.lambda$execute$0(ManagedExecutor.java:36)\n at com.nethunt.crm.api.util.RequestContextActivator.lambda$withRequestContext$0(RequestContextActivator.java:36)\n at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n at java.base/java.lang.Thread.run(Thread.java:748)\nCaused by: javax.mail.SendFailedException: Invalid Addresses;\n nested exception is:\ncom.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:2064)\n at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1286)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendWithSmtp(AutomaticEmailFacade.java:229)\n ... 12 more\nCaused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="java.lang.RuntimeException: javax.mail.SendFailedException: Invalid Addresses;\n nested exception is:\ncom.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendWithSmtp(AutomaticEmailFacade.java:236)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:285)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.lambda$sendSingleEmail$3(AutomaticEmailFacade.java:254)\n at java.util.Optional.ifPresent(Optional.java:159)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:253)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:249)\n at com.nethunt.crm.api.email.EmailSender.lambda$notifyPerson$0(EmailSender.java:80)\n at com.nethunt.crm.api.util.ManagedExecutor.lambda$execute$0(ManagedExecutor.java:36)\n at com.nethunt.crm.api.util.RequestContextActivator.lambda$withRequestContext$0(RequestContextActivator.java:36)\n at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n at java.base/java.lang.Thread.run(Thread.java:748)\nCaused by: javax.mail.SendFailedException: Invalid Addresses;\n nested exception is:\ncom.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:2064)\n at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1286)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendWithSmtp(AutomaticEmailFacade.java:229)\n ... 12 more\nCaused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n"`); err != nil { t.Error(err) } // 5th Python - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n File \"/test/exception.py\", line 21, in \n conn.request(\"GET\", \"/\")\n File \"/usr/lib/python3.10/http/client.py\", line 1282, in request\n self._send_request(method, url, body, headers, encode_chunked)\n File \"/usr/lib/python3.10/http/client.py\", line 1328, in _send_request\n self.endheaders(body, encode_chunked=encode_chunked)\n File \"/usr/lib/python3.10/http/client.py\", line 1277, in endheaders\n self._send_output(message_body, encode_chunked=encode_chunked)\n File \"/usr/lib/python3.10/http/client.py\", line 1037, in _send_output\n self.send(msg)\n File \"/usr/lib/python3.10/http/client.py\", line 975, in send\n self.connect()\n File \"/usr/lib/python3.10/http/client.py\", line 941, in connect\n self.sock = self._create_connection(\n File \"/usr/lib/python3.10/socket.py\", line 824, in create_connection\n for res in getaddrinfo(host, port, 0, SOCK_STREAM):\n File \"/usr/lib/python3.10/socket.py\", line 955, in getaddrinfo\n for res in _socket.getaddrinfo(host, port, family, type, proto, flags):\nsocket.gaierror: [Errno -2] Name or service not known\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n File \"/test/exception.py\", line 21, in \n conn.request(\"GET\", \"/\")\n File \"/usr/lib/python3.10/http/client.py\", line 1282, in request\n self._send_request(method, url, body, headers, encode_chunked)\n File \"/usr/lib/python3.10/http/client.py\", line 1328, in _send_request\n self.endheaders(body, encode_chunked=encode_chunked)\n File \"/usr/lib/python3.10/http/client.py\", line 1277, in endheaders\n self._send_output(message_body, encode_chunked=encode_chunked)\n File \"/usr/lib/python3.10/http/client.py\", line 1037, in _send_output\n self.send(msg)\n File \"/usr/lib/python3.10/http/client.py\", line 975, in send\n self.connect()\n File \"/usr/lib/python3.10/http/client.py\", line 941, in connect\n self.sock = self._create_connection(\n File \"/usr/lib/python3.10/socket.py\", line 824, in create_connection\n for res in getaddrinfo(host, port, 0, SOCK_STREAM):\n File \"/usr/lib/python3.10/socket.py\", line 955, in getaddrinfo\n for res in _socket.getaddrinfo(host, port, family, type, proto, flags):\nsocket.gaierror: [Errno -2] Name or service not known\n"`); err != nil { t.Error(err) } // 6th Python - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n File \"/usr/local/google/home/lujieduan/source/test/exception.py\", line 11, in \n '2' + 2\nTypeError: can only concatenate str (not \"int\") to str\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n File \"/usr/local/google/home/lujieduan/source/test/exception.py\", line 11, in \n '2' + 2\nTypeError: can only concatenate str (not \"int\") to str\n"`); err != nil { t.Error(err) } }) @@ -473,7 +484,7 @@ func TestParseMultilineFileGolangJavaPython(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) config := fmt.Sprintf(`logging: receivers: @@ -498,7 +509,7 @@ func TestParseMultilineFileGolangJavaPython(t *testing.T) { processors: [multiline_parser_1]`, logPath) //Below lines comes from Go, Python and Java exception stacktraces. - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(`2019/01/15 07:48:05 http: panic serving [::1]:54143: test panic + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(`2019/01/15 07:48:05 http: panic serving [::1]:54143: test panic goroutine 24 [running]: net/http.(*conn).serve.func1(0xc00007eaa0) /usr/local/go/src/net/http/server.go:1746 +0xd0 @@ -559,27 +570,27 @@ Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EM t.Fatalf("error writing dummy log lines for Go + Java + Python: %v", err) } - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } // 1st one is Golang - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="2019/01/15 07:48:05 http: panic serving [::1]:54143: test panic\ngoroutine 24 [running]:\nnet/http.(*conn).serve.func1(0xc00007eaa0)\n /usr/local/go/src/net/http/server.go:1746 +0xd0\npanic(0x12472a0, 0x12ece10)\n /usr/local/go/src/runtime/panic.go:513 +0x1b9\nmain.doPanic(0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /Users/ingvar/src/go/src/httppanic.go:8 +0x39\nnet/http.HandlerFunc.ServeHTTP(0x12be2e8, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:1964 +0x44\nnet/http.(*ServeMux).ServeHTTP(0x14a17a0, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:2361 +0x127\nnet/http.serverHandler.ServeHTTP(0xc000085040, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:2741 +0xab\nnet/http.(*conn).serve(0xc00007eaa0, 0x12f10a0, 0xc00008a780)\n /usr/local/go/src/net/http/server.go:1847 +0x646\ncreated by net/http.(*Server).Serve\n /usr/local/go/src/net/http/server.go:2851 +0x2f5\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="2019/01/15 07:48:05 http: panic serving [::1]:54143: test panic\ngoroutine 24 [running]:\nnet/http.(*conn).serve.func1(0xc00007eaa0)\n /usr/local/go/src/net/http/server.go:1746 +0xd0\npanic(0x12472a0, 0x12ece10)\n /usr/local/go/src/runtime/panic.go:513 +0x1b9\nmain.doPanic(0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /Users/ingvar/src/go/src/httppanic.go:8 +0x39\nnet/http.HandlerFunc.ServeHTTP(0x12be2e8, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:1964 +0x44\nnet/http.(*ServeMux).ServeHTTP(0x14a17a0, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:2361 +0x127\nnet/http.serverHandler.ServeHTTP(0xc000085040, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:2741 +0xab\nnet/http.(*conn).serve(0xc00007eaa0, 0x12f10a0, 0xc00008a780)\n /usr/local/go/src/net/http/server.go:1847 +0x646\ncreated by net/http.(*Server).Serve\n /usr/local/go/src/net/http/server.go:2851 +0x2f5\n"`); err != nil { t.Error(err) } // 2nd Python - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n File \"/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py\", line 1535, in __call__\n rv = self.handle_exception(request, response, e)\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 17, in start\n return get()\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 5, in get\n raise Exception('spam', 'eggs')\nException: ('spam', 'eggs')\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n File \"/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py\", line 1535, in __call__\n rv = self.handle_exception(request, response, e)\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 17, in start\n return get()\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 5, in get\n raise Exception('spam', 'eggs')\nException: ('spam', 'eggs')\n"`); err != nil { t.Error(err) } // 3nd Python - With custom string prefix, common when using https://docs.python.org/3/library/logging.html#logging.Logger.exception - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="2023-07-09 00:00:00,000 ERROR some_app custom string prefix to the exception: Traceback (most recent call last):\n File \"/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py\", line 1535, in __call__\n rv = self.handle_exception(request, response, e)\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 17, in start\n return get()\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 5, in get\n raise Exception('spam', 'eggs')\nException: ('spam', 'eggs')\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="2023-07-09 00:00:00,000 ERROR some_app custom string prefix to the exception: Traceback (most recent call last):\n File \"/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py\", line 1535, in __call__\n rv = self.handle_exception(request, response, e)\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 17, in start\n return get()\n File \"/base/data/home/apps/s~nearfieldspy/1.378705245900539993/nearfieldspy.py\", line 5, in get\n raise Exception('spam', 'eggs')\nException: ('spam', 'eggs')\n"`); err != nil { t.Error(err) } // 3rd Java - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="java.lang.RuntimeException: javax.mail.SendFailedException: Invalid Addresses;\n nested exception is:\ncom.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendWithSmtp(AutomaticEmailFacade.java:236)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:285)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.lambda$sendSingleEmail$3(AutomaticEmailFacade.java:254)\n at java.util.Optional.ifPresent(Optional.java:159)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:253)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:249)\n at com.nethunt.crm.api.email.EmailSender.lambda$notifyPerson$0(EmailSender.java:80)\n at com.nethunt.crm.api.util.ManagedExecutor.lambda$execute$0(ManagedExecutor.java:36)\n at com.nethunt.crm.api.util.RequestContextActivator.lambda$withRequestContext$0(RequestContextActivator.java:36)\n at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n at java.base/java.lang.Thread.run(Thread.java:748)\nCaused by: javax.mail.SendFailedException: Invalid Addresses;\n nested exception is:\ncom.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:2064)\n at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1286)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendWithSmtp(AutomaticEmailFacade.java:229)\n ... 12 more\nCaused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="java.lang.RuntimeException: javax.mail.SendFailedException: Invalid Addresses;\n nested exception is:\ncom.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendWithSmtp(AutomaticEmailFacade.java:236)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:285)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.lambda$sendSingleEmail$3(AutomaticEmailFacade.java:254)\n at java.util.Optional.ifPresent(Optional.java:159)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:253)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendSingleEmail(AutomaticEmailFacade.java:249)\n at com.nethunt.crm.api.email.EmailSender.lambda$notifyPerson$0(EmailSender.java:80)\n at com.nethunt.crm.api.util.ManagedExecutor.lambda$execute$0(ManagedExecutor.java:36)\n at com.nethunt.crm.api.util.RequestContextActivator.lambda$withRequestContext$0(RequestContextActivator.java:36)\n at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n at java.base/java.lang.Thread.run(Thread.java:748)\nCaused by: javax.mail.SendFailedException: Invalid Addresses;\n nested exception is:\ncom.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:2064)\n at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1286)\n at com.nethunt.crm.api.server.adminsync.AutomaticEmailFacade.sendWithSmtp(AutomaticEmailFacade.java:229)\n ... 12 more\nCaused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n"`); err != nil { t.Error(err) } }) @@ -592,7 +603,7 @@ func TestParseMultilineFileMissingParser(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) // In the config file, only match for Golang exceptions config := fmt.Sprintf(`logging: @@ -614,7 +625,7 @@ func TestParseMultilineFileMissingParser(t *testing.T) { processors: [multiline_parser_1]`, logPath) //Below lines comes from Go, Python and Java exception stacktraces. - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(`2019/01/15 07:48:05 http: panic serving [::1]:54143: test panic + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(`2019/01/15 07:48:05 http: panic serving [::1]:54143: test panic goroutine 24 [running]: net/http.(*conn).serve.func1(0xc00007eaa0) /usr/local/go/src/net/http/server.go:1746 +0xd0 @@ -667,30 +678,30 @@ Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EM t.Fatalf("error writing dummy log lines for Go + Java + Python: %v", err) } - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } // 1st one is Golang - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="2019/01/15 07:48:05 http: panic serving [::1]:54143: test panic\ngoroutine 24 [running]:\nnet/http.(*conn).serve.func1(0xc00007eaa0)\n /usr/local/go/src/net/http/server.go:1746 +0xd0\npanic(0x12472a0, 0x12ece10)\n /usr/local/go/src/runtime/panic.go:513 +0x1b9\nmain.doPanic(0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /Users/ingvar/src/go/src/httppanic.go:8 +0x39\nnet/http.HandlerFunc.ServeHTTP(0x12be2e8, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:1964 +0x44\nnet/http.(*ServeMux).ServeHTTP(0x14a17a0, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:2361 +0x127\nnet/http.serverHandler.ServeHTTP(0xc000085040, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:2741 +0xab\nnet/http.(*conn).serve(0xc00007eaa0, 0x12f10a0, 0xc00008a780)\n /usr/local/go/src/net/http/server.go:1847 +0x646\ncreated by net/http.(*Server).Serve\n /usr/local/go/src/net/http/server.go:2851 +0x2f5\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="2019/01/15 07:48:05 http: panic serving [::1]:54143: test panic\ngoroutine 24 [running]:\nnet/http.(*conn).serve.func1(0xc00007eaa0)\n /usr/local/go/src/net/http/server.go:1746 +0xd0\npanic(0x12472a0, 0x12ece10)\n /usr/local/go/src/runtime/panic.go:513 +0x1b9\nmain.doPanic(0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /Users/ingvar/src/go/src/httppanic.go:8 +0x39\nnet/http.HandlerFunc.ServeHTTP(0x12be2e8, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:1964 +0x44\nnet/http.(*ServeMux).ServeHTTP(0x14a17a0, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:2361 +0x127\nnet/http.serverHandler.ServeHTTP(0xc000085040, 0x12f0ea0, 0xc00010e1c0, 0xc000104400)\n /usr/local/go/src/net/http/server.go:2741 +0xab\nnet/http.(*conn).serve(0xc00007eaa0, 0x12f10a0, 0xc00008a780)\n /usr/local/go/src/net/http/server.go:1847 +0x646\ncreated by net/http.(*Server).Serve\n /usr/local/go/src/net/http/server.go:2851 +0x2f5\n"`); err != nil { t.Error(err) } // 2nd one is Python - the golang parser will send those lines as single-line logs - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="Traceback (most recent call last):\n"`); err != nil { t.Error(err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message=" raise Exception('spam', 'eggs')\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message=" raise Exception('spam', 'eggs')\n"`); err != nil { t.Error(err) } // 3rd one is Java - the golang parser will send those lines as single-line logs - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="java.lang.RuntimeException: javax.mail.SendFailedException: Invalid Addresses;\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="java.lang.RuntimeException: javax.mail.SendFailedException: Invalid Addresses;\n"`); err != nil { t.Error(err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "files_1", time.Hour, `jsonPayload.message="Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "files_1", time.Hour, `jsonPayload.message="Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.7.1 <[REDACTED_EMAIL_ADDRESS]>... Relaying denied\n"`); err != nil { t.Error(err) } }) @@ -700,7 +711,7 @@ func TestCustomLogFile(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) config := fmt.Sprintf(`logging: receivers: @@ -725,19 +736,19 @@ func TestCustomLogFile(t *testing.T) { exporters: [google] `, logPath) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader("abc test pattern xyz\n7654321\n"), logPath); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader("abc test pattern xyz\n7654321\n"), logPath); err != nil { t.Fatalf("error writing dummy log line: %v", err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "mylog_source", time.Hour, "jsonPayload.message=7654321"); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "mylog_source", time.Hour, "jsonPayload.message=7654321"); err != nil { t.Error(err) } time.Sleep(60 * time.Second) - _, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "mylog_source", time.Hour, `jsonPayload.message="abc test pattern xyz"`, 5) + _, err := gce.QueryLog(ctx, logger, vm, "mylog_source", time.Hour, `jsonPayload.message="abc test pattern xyz"`, 5) if err == nil { t.Error("expected log to be excluded but was included") } else if !strings.Contains(err.Error(), "not found, exhausted retries") { @@ -750,7 +761,7 @@ func TestCustomLogFormat(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) config := fmt.Sprintf(`logging: @@ -776,18 +787,18 @@ func TestCustomLogFormat(t *testing.T) { exporters: [google] `, logPath, "%Y-%m-%dT%H:%M:%S.%L%z") - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } zone := time.FixedZone("UTC-8", int((-8 * time.Hour).Seconds())) line := fmt.Sprintf("<13>1 %s %s my_app_id - - - qqqqrrrr\n", time.Now().In(zone).Format(time.RFC3339Nano), vm.Name) - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), logPath); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), logPath); err != nil { t.Fatalf("error writing dummy log line: %v", err) } // window (1 hour) is *less than* the time zone UTC offset (8 hours) to catch time zone parse failures - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "mylog_source", time.Hour, "jsonPayload.message=qqqqrrrr AND jsonPayload.ident=my_app_id"); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "mylog_source", time.Hour, "jsonPayload.message=qqqqrrrr AND jsonPayload.ident=my_app_id"); err != nil { t.Error(err) } }) @@ -798,7 +809,7 @@ func TestHTTPRequestLog(t *testing.T) { gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) config := fmt.Sprintf(`logging: receivers: @@ -820,7 +831,7 @@ func TestHTTPRequestLog(t *testing.T) { processors: [json1] exporters: [google]`, logPath) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } @@ -858,7 +869,7 @@ func TestHTTPRequestLog(t *testing.T) { // Write both logs to log source file at the same time. err = gce.UploadContent( ctx, - logger.ToMainLog(), + logger, vm, strings.NewReader(fmt.Sprintf("%s\n%s\n", string(newLogBytes), string(oldLogBytes))), logPath) @@ -869,7 +880,7 @@ func TestHTTPRequestLog(t *testing.T) { queryLogById := func(logId string) (*cloudlogging.Entry, error) { return gce.QueryLog( ctx, - logger.ToMainLog(), + logger, vm, "mylog_source", time.Hour, @@ -925,7 +936,7 @@ func TestInvalidConfig(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) // Sample bad config sourced from: // https://github.com/GoogleCloudPlatform/ops-agent/blob/master/confgenerator/testdata/invalid/linux/logging-receiver_reserved_id_prefix/input.yaml @@ -942,7 +953,7 @@ func TestInvalidConfig(t *testing.T) { ` // Run install with an invalid config. We expect to see an error. - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err == nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err == nil { t.Fatal("Expected agent to reject bad config.") } }) @@ -958,7 +969,7 @@ func TestProcessorOrder(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) config := fmt.Sprintf(`logging: @@ -987,18 +998,18 @@ func TestProcessorOrder(t *testing.T) { exporters: [google] `, logPath, "%Y-%m-%dT%H:%M:%S.%L%z") - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } // When not using UTC timestamps, the parsing with "%Y-%m-%dT%H:%M:%S.%L%z" doesn't work // correctly in windows (b/218888265). line := fmt.Sprintf(`{"log":"{\"level\":\"info\",\"message\":\"start\"}\n","time":"%s"}`, time.Now().UTC().Format(time.RFC3339Nano)) + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), logPath); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), logPath); err != nil { t.Fatalf("error writing dummy log line: %v", err) } - entry, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "mylog_source", time.Hour, "", gce.QueryMaxAttempts) + entry, err := gce.QueryLog(ctx, logger, vm, "mylog_source", time.Hour, "", gce.QueryMaxAttempts) if err != nil { t.Fatal(err) } @@ -1025,7 +1036,7 @@ func TestSyslogTCP(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) config := `logging: receivers: @@ -1050,7 +1061,7 @@ func TestSyslogTCP(t *testing.T) { exporters: [google] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } @@ -1059,19 +1070,19 @@ func TestSyslogTCP(t *testing.T) { // detecting a failure if the exclusion message were to actually be included. // Write test message for exclusion using the program called logger. - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", "logger -n 0.0.0.0 --tcp --port=5140 -- abc test pattern xyz"); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", "logger -n 0.0.0.0 --tcp --port=5140 -- abc test pattern xyz"); err != nil { t.Fatalf("Error writing dummy log line: %v", err) } // Write test message for inclusion. - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", "logger -n 0.0.0.0 --tcp --port=5140 -- abcdefg"); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", "logger -n 0.0.0.0 --tcp --port=5140 -- abcdefg"); err != nil { t.Fatalf("Error writing dummy log line: %v", err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "mylog_source", time.Hour, "jsonPayload.message:abcdefg"); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "mylog_source", time.Hour, "jsonPayload.message:abcdefg"); err != nil { t.Error(err) } time.Sleep(60 * time.Second) - _, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "mylog_source", time.Hour, `jsonPayload.message:"test pattern"`, 5) + _, err := gce.QueryLog(ctx, logger, vm, "mylog_source", time.Hour, `jsonPayload.message:"test pattern"`, 5) if err == nil { t.Error("expected log to be excluded but was included") } else if !strings.Contains(err.Error(), "not found, exhausted retries") { @@ -1087,7 +1098,7 @@ func TestSyslogUDP(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) config := `logging: receivers: @@ -1106,16 +1117,16 @@ func TestSyslogUDP(t *testing.T) { exporters: [google] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } // Write "abcdefg" using the program called logger. - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", "logger -n 0.0.0.0 --udp --port=5140 -- abcdefg"); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", "logger -n 0.0.0.0 --udp --port=5140 -- abcdefg"); err != nil { t.Fatalf("Error writing dummy log line: %v", err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "mylog_source", time.Hour, "jsonPayload.message:abcdefg"); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "mylog_source", time.Hour, "jsonPayload.message:abcdefg"); err != nil { t.Error(err) } }) @@ -1125,7 +1136,7 @@ func TestExcludeLogs(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) file1 := fmt.Sprintf("%s_1", logPathForPlatform(vm.Platform)) file2 := fmt.Sprintf("%s_2", logPathForPlatform(vm.Platform)) @@ -1163,28 +1174,28 @@ func TestExcludeLogs(t *testing.T) { processors: [json, exclude2] `, file1, file2) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } logContents1 := `{"field":"string containing pattern"}` + "\n" logContents1 += `{"field":"other"}` + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(logContents1), file1); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(logContents1), file1); err != nil { t.Fatalf("error uploading log: %v", err) } logContents2 := `{"field1":"nope, include me!", "field2":"second"}` + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(logContents2), file2); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(logContents2), file2); err != nil { t.Fatalf("error uploading log: %v", err) } // p1: Expect to see the log that doesn't have pattern in it. - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "f1", time.Hour, `jsonPayload.field:"other"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "f1", time.Hour, `jsonPayload.field:"other"`); err != nil { t.Error(err) } // p1: Give the excluded log some time to show up. time.Sleep(60 * time.Second) - _, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "f1", time.Hour, `jsonPayload.field:"pattern"`, 5) + _, err := gce.QueryLog(ctx, logger, vm, "f1", time.Hour, `jsonPayload.field:"pattern"`, 5) if err == nil { t.Error("expected log to be excluded but was included") } else if !strings.Contains(err.Error(), "not found, exhausted retries") { @@ -1192,7 +1203,7 @@ func TestExcludeLogs(t *testing.T) { } // p2: Expect to see the log. - resultingLog2, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "f2", time.Hour, `jsonPayload.field1:*`, gce.QueryMaxAttempts) + resultingLog2, err := gce.QueryLog(ctx, logger, vm, "f2", time.Hour, `jsonPayload.field1:*`, gce.QueryMaxAttempts) if err != nil { t.Error(err) } @@ -1210,7 +1221,7 @@ func TestExcludeLogsParseJsonOrder(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) file1 := fmt.Sprintf("%s_1", logPathForPlatform(vm.Platform)) file2 := fmt.Sprintf("%s_2", logPathForPlatform(vm.Platform)) @@ -1258,25 +1269,25 @@ func TestExcludeLogsParseJsonOrder(t *testing.T) { exporters: [google] `, file1, file2) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } line := `{"field":"value"}` + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), file2); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), file2); err != nil { t.Fatalf("error uploading log: %v", err) } - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), file1); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), file1); err != nil { t.Fatalf("error uploading log: %v", err) } // Expect to see the log included in p1 but not p2. - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "f1", time.Hour, `jsonPayload.field="value"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "f1", time.Hour, `jsonPayload.field="value"`); err != nil { t.Error(err) } // Give the excluded log some time to show up. time.Sleep(60 * time.Second) - _, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "f2", time.Hour, `jsonPayload.field="value"`, 5) + _, err := gce.QueryLog(ctx, logger, vm, "f2", time.Hour, `jsonPayload.field="value"`, 5) if err == nil { t.Error("expected log to be excluded but was included") } else if !strings.Contains(err.Error(), "not found, exhausted retries") { @@ -1289,7 +1300,7 @@ func TestModifyFields(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) file1 := fmt.Sprintf("%s_1", logPathForPlatform(vm.Platform)) config := fmt.Sprintf(`logging: @@ -1344,17 +1355,17 @@ func TestModifyFields(t *testing.T) { exporters: [google] `, file1) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } line := `{"field":"value", "default_present":"original", "logging.googleapis.com/labels": {"label1":"value"}}` + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), file1); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), file1); err != nil { t.Fatalf("error uploading log: %v", err) } // Expect to see the log with the modifications applied - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "f1", time.Hour, `jsonPayload.field2="value" AND labels.static="hello world" AND labels.label2="value" AND NOT labels.label1:* AND labels."my.cool.service/foo"="value" AND severity="WARNING" AND NOT jsonPayload.field:* AND jsonPayload.default_present="original" AND jsonPayload.default_absent="default" AND jsonPayload.integer > 5 AND jsonPayload.float > 5 AND jsonPayload.mapped_field="new_value" AND (NOT jsonPayload.omitted = "broken")`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "f1", time.Hour, `jsonPayload.field2="value" AND labels.static="hello world" AND labels.label2="value" AND NOT labels.label1:* AND labels."my.cool.service/foo"="value" AND severity="WARNING" AND NOT jsonPayload.field:* AND jsonPayload.default_present="original" AND jsonPayload.default_absent="default" AND jsonPayload.integer > 5 AND jsonPayload.float > 5 AND jsonPayload.mapped_field="new_value" AND (NOT jsonPayload.omitted = "broken")`); err != nil { t.Error(err) } }) @@ -1364,7 +1375,7 @@ func TestParseWithConflictsWithRecord(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) file1 := fmt.Sprintf("%s_1", logPathForPlatform(vm.Platform)) configStr := ` logging: @@ -1410,17 +1421,17 @@ logging: - google ` config := fmt.Sprintf(configStr, file1) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } line := `{"parsed-field":"parsed-value", "overwritten-field":"overwritten", "logging.googleapis.com/labels": {"parsed-label":"parsed-label", "overwritten-label":"overwritten"}, "logging.googleapis.com/sourceLocation": {"file": "overwritten-file-path"}}` + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), file1); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), file1); err != nil { t.Fatalf("error uploading log: %v", err) } // Expect to see the log with the modifications applied - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "f1", time.Hour, + if err := gce.WaitForLog(ctx, logger, vm, "f1", time.Hour, `jsonPayload.original-field="original-value" AND jsonPayload.parsed-field="parsed-value" AND jsonPayload.non-overwritten-field="non-overwritten" AND jsonPayload.overwritten-field="overwritten" AND labels.original-label="original-label" AND labels.parsed-label="parsed-label" AND labels.non-overwritten-label="non-overwritten" AND labels.overwritten-label="overwritten" AND severity="WARNING" AND sourceLocation.file="overwritten-file-path"`); err != nil { t.Error(err) } @@ -1431,7 +1442,7 @@ func TestResourceNameLabel(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) file1 := fmt.Sprintf("%s_1", logPathForPlatform(vm.Platform)) config := fmt.Sprintf(`logging: @@ -1450,18 +1461,18 @@ func TestResourceNameLabel(t *testing.T) { processors: [json] `, file1) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } line := `{"default_present":"original"}` + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), file1); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), file1); err != nil { t.Fatalf("error uploading log: %v", err) } // Expect to see the log with the modifications applied check := fmt.Sprintf(`labels."compute.googleapis.com/resource_name"="%s" AND jsonPayload.default_present="original"`, vm.Name) - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "f1", time.Hour, check); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "f1", time.Hour, check); err != nil { t.Error(err) } }) @@ -1471,7 +1482,7 @@ func TestLogFilePathLabel(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) file1 := fmt.Sprintf("%s_1", logPathForPlatform(vm.Platform)) config := fmt.Sprintf(`logging: @@ -1491,12 +1502,12 @@ func TestLogFilePathLabel(t *testing.T) { processors: [json] `, file1) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } line := `{"default_present":"original"}` + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), file1); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), file1); err != nil { t.Fatalf("error uploading log: %v", err) } @@ -1509,7 +1520,7 @@ func TestLogFilePathLabel(t *testing.T) { // Expect to see log with label added. check := fmt.Sprintf(`labels."agent.googleapis.com/log_file_path"="%s" AND jsonPayload.default_present="original"`, file1) - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "f1", time.Hour, check); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "f1", time.Hour, check); err != nil { t.Error(err) } }) @@ -1519,7 +1530,7 @@ func TestLogFilePathLabel(t *testing.T) { // path is returned by this function) and pipes its contents to an output configured via outputConfig. // An example outputConfig would be "-o tcp://127.0.0.1:5170". // Use parseInputAsJSON for structured input. -func startFluentBitBackgroundPipe(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, platform string, parseInputAsJSON bool, outputConfig string) (string, error) { +func startFluentBitBackgroundPipe(ctx context.Context, logger *log.Logger, vm *gce.VM, platform string, parseInputAsJSON bool, outputConfig string) (string, error) { dir := workDirForPlatform(platform) if err := makeDirectory(ctx, logger, vm, dir); err != nil { return "", err @@ -1565,7 +1576,7 @@ EOF fluentBitArgs) } - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", command); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", command); err != nil { return "", err } return remoteFile, nil @@ -1574,13 +1585,13 @@ EOF // writeLinesToRemoteFile writes lines of text to a remote file. // Lines each have an implicit terminating newline character. // Lines are allowed to be huge. -func writeLinesToRemoteFile(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, platform string, remoteFile string, lines ...string) error { +func writeLinesToRemoteFile(ctx context.Context, logger *log.Logger, vm *gce.VM, platform string, remoteFile string, lines ...string) error { for _, line := range lines { line += "\n" // Use a temp-file as a buffer to allow for long lines. tempPath := filepath.Join(workDirForPlatform(platform), "pipe_temp.log") - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), tempPath); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), tempPath); err != nil { return err } @@ -1590,7 +1601,7 @@ func writeLinesToRemoteFile(ctx context.Context, logger *logging.DirectoryLogger appendCommand = fmt.Sprintf(`Get-Content %s | Out-File -Encoding Ascii -Append %s`, tempPath, remoteFile) } - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", appendCommand); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", appendCommand); err != nil { return err } } @@ -1602,7 +1613,7 @@ func TestTCPLog(t *testing.T) { gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) config := `logging: receivers: @@ -1617,7 +1628,7 @@ func TestTCPLog(t *testing.T) { receivers: [tcp_logs] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } @@ -1649,7 +1660,7 @@ func TestTCPLog(t *testing.T) { waitGroup.Add(1) go func() { defer waitGroup.Done() - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "tcp_logs", time.Hour, query); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "tcp_logs", time.Hour, query); err != nil { t.Error(err) } }() @@ -1668,7 +1679,7 @@ func TestFluentForwardLog(t *testing.T) { gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) config := `logging: receivers: @@ -1681,7 +1692,7 @@ func TestFluentForwardLog(t *testing.T) { fluent_pipeline: receivers: [fluent_logs] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } @@ -1699,7 +1710,7 @@ func TestFluentForwardLog(t *testing.T) { t.Fatalf("Error writing dummy TCP log line: %v", err) } - if err = gce.WaitForLog(ctx, logger.ToMainLog(), vm, "fluent_logs.forwarder_tag", time.Hour, `jsonPayload.large:"start" AND jsonPayload.large:"end"`); err != nil { + if err = gce.WaitForLog(ctx, logger, vm, "fluent_logs.forwarder_tag", time.Hour, `jsonPayload.large:"start" AND jsonPayload.large:"end"`); err != nil { t.Error(err) } }) @@ -1712,7 +1723,7 @@ func TestWindowsEventLog(t *testing.T) { if !gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) config := `logging: receivers: @@ -1728,7 +1739,7 @@ func TestWindowsEventLog(t *testing.T) { receivers: [windows_event_log] exporters: [google] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } @@ -1737,13 +1748,13 @@ func TestWindowsEventLog(t *testing.T) { "System": "system_msg", } for log, payload := range payloads { - if err := writeToWindowsEventLog(ctx, logger.ToMainLog(), vm, log, payload); err != nil { + if err := writeToWindowsEventLog(ctx, logger, vm, log, payload); err != nil { t.Fatal(err) } } for _, payload := range payloads { - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "windows_event_log", time.Hour, logMessageQueryForPlatform(vm.Platform, payload)); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "windows_event_log", time.Hour, logMessageQueryForPlatform(vm.Platform, payload)); err != nil { t.Fatal(err) } } @@ -1757,7 +1768,7 @@ func TestWindowsEventLogV1UnsupportedChannel(t *testing.T) { if !gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) log := "windows_event_log" channel := "Microsoft-Windows-User Control Panel/Operational" @@ -1773,13 +1784,13 @@ func TestWindowsEventLogV1UnsupportedChannel(t *testing.T) { default_pipeline: receivers: [%s] `, log, channel, log) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } // Quote-and-escape the query string so that Cloud Logging accepts it expectedWarning := fmt.Sprintf(`"\"channels[1]\" contains a channel, \"%s\", which may not work properly on version 1 of windows_event_log"`, channel) - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, log, time.Hour, logMessageQueryForPlatform(vm.Platform, expectedWarning)); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, log, time.Hour, logMessageQueryForPlatform(vm.Platform, expectedWarning)); err != nil { t.Fatal(err) } }) @@ -1792,7 +1803,7 @@ func TestWindowsEventLogV2(t *testing.T) { if !gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) // Have to wait for startup feature tracking metrics to be sent // before we tear down the service. @@ -1832,7 +1843,7 @@ func TestWindowsEventLogV2(t *testing.T) { pipeline_xml: receivers: [winlog2_xml] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } @@ -1855,19 +1866,19 @@ func TestWindowsEventLogV2(t *testing.T) { } for r := range payloads { for log, payload := range payloads[r] { - if err := writeToWindowsEventLog(ctx, logger.ToMainLog(), vm, log, payload); err != nil { + if err := writeToWindowsEventLog(ctx, logger, vm, log, payload); err != nil { t.Fatal(err) } } } // Manually re-send a log as a Warning to test severity parsing. - if err := writeToWindowsEventLogWithSeverity(ctx, logger.ToMainLog(), vm, "Application", "warning_msg", "Warning"); err != nil { + if err := writeToWindowsEventLogWithSeverity(ctx, logger, vm, "Application", "warning_msg", "Warning"); err != nil { t.Fatal(err) } // For winlog2_space, we simply check that the logs were ingested. for _, payload := range payloads["winlog2_space"] { - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "winlog2_space", time.Hour, logMessageQueryForPlatform(vm.Platform, payload)); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "winlog2_space", time.Hour, logMessageQueryForPlatform(vm.Platform, payload)); err != nil { t.Fatal(err) } } @@ -1878,16 +1889,16 @@ func TestWindowsEventLogV2(t *testing.T) { for _, payload := range payloads["winlog2_default"] { queryV1 := logMessageQueryForPlatform(vm.Platform, payload) + " AND jsonPayload.TimeGenerated:*" queryV2 := logMessageQueryForPlatform(vm.Platform, payload) + " AND jsonPayload.TimeCreated:*" - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "windows_event_log", time.Hour, queryV1); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "windows_event_log", time.Hour, queryV1); err != nil { t.Fatalf("expected v1 log for %s but it wasn't found: err=%v", payload, err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "winlog2_default", time.Hour, queryV2); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "winlog2_default", time.Hour, queryV2); err != nil { t.Fatalf("expected v2 log for %s but it wasn't found: err=%v", payload, err) } } // Verify that the warning message has the correct severity. - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "winlog2_default", time.Hour, logMessageQueryForPlatform(vm.Platform, "warning_msg")+` AND severity="WARNING"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "winlog2_default", time.Hour, logMessageQueryForPlatform(vm.Platform, "warning_msg")+` AND severity="WARNING"`); err != nil { t.Fatal(err) } @@ -1896,7 +1907,7 @@ func TestWindowsEventLogV2(t *testing.T) { // - that jsonPayload.raw_xml contains a valid XML document. // - that a few sample fields are present in that XML document. for _, payload := range payloads["winlog2_xml"] { - log, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "winlog2_xml", time.Hour, logMessageQueryForPlatform(vm.Platform, payload), gce.QueryMaxAttempts) + log, err := gce.QueryLog(ctx, logger, vm, "winlog2_xml", time.Hour, logMessageQueryForPlatform(vm.Platform, payload), gce.QueryMaxAttempts) if err != nil { t.Fatal(err) } @@ -2017,7 +2028,7 @@ func TestWindowsEventLogV2(t *testing.T) { }, } - series, err := gce.WaitForMetricSeries(ctx, logger.ToMainLog(), vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", 2*time.Hour, nil, false, len(expectedFeatures)) + series, err := gce.WaitForMetricSeries(ctx, logger, vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", 2*time.Hour, nil, false, len(expectedFeatures)) if err != nil { t.Error(err) return @@ -2047,24 +2058,24 @@ func TestWindowsEventLogWithNonDefaultTimeZone(t *testing.T) { if !gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", `Set-TimeZone -Id "Eastern Standard Time"`); err != nil { + ctx, logger, vm := setupMainLogAndVM(t, platform) + if _, err := gce.RunRemotely(ctx, logger, vm, "", `Set-TimeZone -Id "Eastern Standard Time"`); err != nil { t.Fatal(err) } - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } // Write an event and record its approximate time testMessage := "TestWindowsEventLogWithNonDefaultTimeZone" - if err := writeToSystemLog(ctx, logger.ToMainLog(), vm, testMessage); err != nil { + if err := writeToSystemLog(ctx, logger, vm, testMessage); err != nil { t.Fatal(err) } eventTime := time.Now() // Validate that the log written to Cloud Logging has a timestamp that's // close to eventTime. Use 24*time.Hour to cover all possible time zones. - logEntry, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "windows_event_log", 24*time.Hour, logMessageQueryForPlatform(platform, testMessage), gce.QueryMaxAttempts) + logEntry, err := gce.QueryLog(ctx, logger, vm, "windows_event_log", 24*time.Hour, logMessageQueryForPlatform(platform, testMessage), gce.QueryMaxAttempts) if err != nil { t.Fatal(err) } @@ -2082,7 +2093,7 @@ func TestSystemdLog(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) config := `logging: receivers: @@ -2094,15 +2105,15 @@ func TestSystemdLog(t *testing.T) { receivers: [systemd_logs] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", "echo 'my_systemd_log_message' | systemd-cat"); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", "echo 'my_systemd_log_message' | systemd-cat"); err != nil { t.Fatalf("Error writing dummy Systemd log line: %v", err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "systemd_logs", time.Hour, "my_systemd_log_message"); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "systemd_logs", time.Hour, "my_systemd_log_message"); err != nil { t.Error(err) } }) @@ -2112,28 +2123,28 @@ func TestSystemLogByDefault(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } - if err := writeToSystemLog(ctx, logger.ToMainLog(), vm, "123456789"); err != nil { + if err := writeToSystemLog(ctx, logger, vm, "123456789"); err != nil { t.Fatal(err) } tag := systemLogTagForPlatform(vm.Platform) - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, tag, time.Hour, logMessageQueryForPlatform(vm.Platform, "123456789")); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, tag, time.Hour, logMessageQueryForPlatform(vm.Platform, "123456789")); err != nil { t.Error(err) } }) } -func testDefaultMetrics(ctx context.Context, t *testing.T, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) { +func testDefaultMetrics(ctx context.Context, t *testing.T, logger *log.Logger, vm *gce.VM, window time.Duration) { if !gce.IsWindows(vm.Platform) { // Enable swap file: https://linuxize.com/post/create-a-linux-swap-file/ // We do this so that swap file metrics will show up. - _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", strings.Join([]string{ + _, err := gce.RunRemotely(ctx, logger, vm, "", strings.Join([]string{ "sudo dd if=/dev/zero of=/swapfile bs=1024 count=102400", "sudo chmod 600 /swapfile", "(sudo mkswap /swapfile || sudo /usr/sbin/mkswap /swapfile)", @@ -2166,7 +2177,7 @@ func testDefaultMetrics(ctx context.Context, t *testing.T, logger *logging.Direc } var series *monitoringpb.TimeSeries - series, err = gce.WaitForMetric(ctx, logger.ToMainLog(), vm, metric.Type, window, nil, false) + series, err = gce.WaitForMetric(ctx, logger, vm, metric.Type, window, nil, false) if err != nil { t.Fatal(err) } @@ -2205,7 +2216,7 @@ func testDefaultMetrics(ctx context.Context, t *testing.T, logger *logging.Direc metricsWaitGroup.Add(1) go func() { defer metricsWaitGroup.Done() - series, err := gce.WaitForMetric(ctx, logger.ToMainLog(), vm, metric.Type, window, nil, false) + series, err := gce.WaitForMetric(ctx, logger, vm, metric.Type, window, nil, false) if err != nil { t.Error(err) return @@ -2232,7 +2243,7 @@ func testDefaultMetrics(ctx context.Context, t *testing.T, logger *logging.Direc t.Fatal(err) } - series, err := gce.WaitForMetricSeries(ctx, logger.ToMainLog(), vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", window, nil, false, len(fc.Features)) + series, err := gce.WaitForMetricSeries(ctx, logger, vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", window, nil, false, len(fc.Features)) if err != nil { t.Error(err) return @@ -2250,8 +2261,8 @@ func TestDefaultMetricsNoProxy(t *testing.T) { gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + ctx, logger, vm := setupMainLogAndVM(t, platform) + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } @@ -2275,15 +2286,15 @@ func TestDefaultMetricsWithProxy(t *testing.T) { if err := json.Unmarshal([]byte(proxySettingsVal), &settings); err != nil { t.Fatal(err) } - ctx, logger, vm := agents.CommonSetup(t, platform) - if err := gce.SetEnvironmentVariables(ctx, logger.ToMainLog(), vm, settings); err != nil { + ctx, logger, vm := setupMainLogAndVM(t, platform) + if err := gce.SetEnvironmentVariables(ctx, logger, vm, settings); err != nil { t.Fatal(err) } - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } - if err := gce.RemoveExternalIP(ctx, logger.ToMainLog(), vm); err != nil { + if err := gce.RemoveExternalIP(ctx, logger, vm); err != nil { t.Fatal(err) } // Sleep for 3 minutes to make sure that if any metrics were sent between agent install and removal of the IP address, then they will fall out of the 2 minute window. @@ -2296,7 +2307,7 @@ func TestPrometheusMetrics(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) promConfig := `metrics: receivers: @@ -2348,7 +2359,7 @@ func TestPrometheusMetrics(t *testing.T) { - prometheus ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, promConfig); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, promConfig); err != nil { t.Fatal(err) } @@ -2359,7 +2370,7 @@ func TestPrometheusMetrics(t *testing.T) { existingMetric := "prometheus.googleapis.com/fluentbit_uptime/counter" window := time.Minute - metric, err := gce.WaitForMetric(ctx, logger.ToMainLog(), vm, existingMetric, window, nil, true) + metric, err := gce.WaitForMetric(ctx, logger, vm, existingMetric, window, nil, true) if err != nil { t.Fatal(fmt.Errorf("failed to find metric %q in VM %q: %w", existingMetric, vm.Name, err)) } @@ -2463,7 +2474,7 @@ func TestPrometheusMetrics(t *testing.T) { }, } - series, err := gce.WaitForMetricSeries(ctx, logger.ToMainLog(), vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", time.Hour, nil, false, len(expectedFeatures)) + series, err := gce.WaitForMetricSeries(ctx, logger, vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", time.Hour, nil, false, len(expectedFeatures)) if err != nil { t.Error(err) return @@ -2487,7 +2498,7 @@ func TestPrometheusMetricsWithJSONExporter(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) prometheusTestdata := path.Join("testdata", "prometheus") filesToUpload := []fileToUpload{ { @@ -2532,7 +2543,7 @@ func TestPrometheusMetricsWithJSONExporter(t *testing.T) { } // Wait until both are ready time.Sleep(30 * time.Second) - liveCheckOut, liveCheckErr := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", `curl "http://localhost:7979/probe?module=default&target=http://localhost:8000/data.json"`) + liveCheckOut, liveCheckErr := gce.RunRemotely(ctx, logger, vm, "", `curl "http://localhost:7979/probe?module=default&target=http://localhost:8000/data.json"`) // We will abort when: // 1. JSON exporter is not started: in this case the stderr will have: // "curl: (7) Failed to connect to localhost port 7979 after 1 ms: Connection refused" @@ -2581,7 +2592,7 @@ func TestPrometheusMetricsWithJSONExporter(t *testing.T) { prom_pipeline: receivers: [prom_app] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } @@ -2646,8 +2657,8 @@ func TestPrometheusRelabelConfigs(t *testing.T) { local: path.Join(prometheusTestdata, "sample_label_replace"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { - if pts, err := gce.WaitForMetric(ctx, logger.ToMainLog(), vm, "prometheus.googleapis.com/test_metric/gauge", window, nil, true); err != nil { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { + if pts, err := gce.WaitForMetric(ctx, logger, vm, "prometheus.googleapis.com/test_metric/gauge", window, nil, true); err != nil { return err } else { labelValue, ok := pts.Metric.Labels["test_label"] @@ -2690,7 +2701,7 @@ func TestPrometheusUntypedMetrics(t *testing.T) { local: path.Join(prometheusTestdata, "sample_untyped"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { tests := []prometheusMetricTest{ {"prometheus.googleapis.com/explicit_untyped_metric/unknown", nil, metric.MetricDescriptor_GAUGE, metric.MetricDescriptor_DOUBLE, 1.0}, @@ -2713,10 +2724,10 @@ func TestPrometheusUntypedMetrics(t *testing.T) { } // Ensure that the gauge-casted metric isn't reported when the unknown typed one is. - if err := gce.AssertMetricMissing(ctx, logger.ToMainLog(), vm, "prometheus.googleapis.com/explicit_untyped_metric/gauge", true, window); err != nil { + if err := gce.AssertMetricMissing(ctx, logger, vm, "prometheus.googleapis.com/explicit_untyped_metric/gauge", true, window); err != nil { t.Error(err) } - if err := gce.AssertMetricMissing(ctx, logger.ToMainLog(), vm, "prometheus.googleapis.com/missing_type_hint_metric/gauge", true, window); err != nil { + if err := gce.AssertMetricMissing(ctx, logger, vm, "prometheus.googleapis.com/missing_type_hint_metric/gauge", true, window); err != nil { t.Error(err) } return multiErr @@ -2751,7 +2762,7 @@ func TestPrometheusUntypedMetricsReset(t *testing.T) { local: path.Join(prometheusTestdata, "sample_untyped_step_1"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { tests := []prometheusMetricTest{ {"prometheus.googleapis.com/untyped_metric/unknown", nil, metric.MetricDescriptor_GAUGE, metric.MetricDescriptor_DOUBLE, 10.0}, @@ -2776,7 +2787,7 @@ func TestPrometheusUntypedMetricsReset(t *testing.T) { local: path.Join(prometheusTestdata, "sample_untyped_step_2"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { tests := []prometheusMetricTest{ {"prometheus.googleapis.com/untyped_metric/unknown", nil, metric.MetricDescriptor_GAUGE, metric.MetricDescriptor_DOUBLE, 100.0}, @@ -2802,7 +2813,7 @@ func TestPrometheusUntypedMetricsReset(t *testing.T) { local: path.Join(prometheusTestdata, "sample_untyped_step_3"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { tests := []prometheusMetricTest{ {"prometheus.googleapis.com/untyped_metric/unknown", nil, metric.MetricDescriptor_GAUGE, metric.MetricDescriptor_DOUBLE, 10.0}, @@ -2825,7 +2836,7 @@ func TestPrometheusUntypedMetricsReset(t *testing.T) { local: path.Join(prometheusTestdata, "sample_untyped_step_4"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { tests := []prometheusMetricTest{ {"prometheus.googleapis.com/untyped_metric/unknown", nil, metric.MetricDescriptor_GAUGE, metric.MetricDescriptor_DOUBLE, 1000.0}, @@ -2932,7 +2943,7 @@ func TestPrometheusHistogramMetrics(t *testing.T) { local: path.Join(prometheusTestdata, "sample_histogram_step_1"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { return assertPrometheusHistogramMetric(ctx, logger, vm, "test_histogram", window, stepOneExpected) }, }) @@ -2941,7 +2952,7 @@ func TestPrometheusHistogramMetrics(t *testing.T) { local: path.Join(prometheusTestdata, "sample_histogram_step_2"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { return assertPrometheusHistogramMetric(ctx, logger, vm, "test_histogram", window, stepTwoExpected) }, }) @@ -3020,7 +3031,7 @@ func TestPrometheusSummaryMetrics(t *testing.T) { local: path.Join(prometheusTestdata, "sample_summary_step_1"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { return assertPrometheusSummaryMetric(ctx, logger, vm, "test_summary", window, stepOneExpected) }, }) @@ -3029,7 +3040,7 @@ func TestPrometheusSummaryMetrics(t *testing.T) { local: path.Join(prometheusTestdata, "sample_summary_step_2"), remote: path.Join(remoteWorkDir, "data"), }, - check: func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error { + check: func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error { return assertPrometheusSummaryMetric(ctx, logger, vm, "test_summary", window, stepTwoExpected) }, }) @@ -3049,7 +3060,7 @@ func testPrometheusMetrics(t *testing.T, opsAgentConfig string, testChecks []moc if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) prometheusTestdata := path.Join("testdata", "prometheus") remoteWorkDir := path.Join("/opt", "go-http-server") @@ -3076,21 +3087,19 @@ func testPrometheusMetrics(t *testing.T, opsAgentConfig string, testChecks []moc if err := installGolang(ctx, logger, vm); err != nil { t.Fatal(err) } - setupScript := `sudo systemctl daemon-reload - sudo systemctl enable http-server-for-prometheus-test - sudo systemctl restart http-server-for-prometheus-test` - setupOut, err := gce.RunScriptRemotely(ctx, logger, vm, string(setupScript), nil, nil) + setupScript := `sudo systemctl daemon-reload && sudo systemctl enable http-server-for-prometheus-test && sudo systemctl restart http-server-for-prometheus-test` + setupOut, err := gce.RunRemotely(ctx, logger, vm, "", setupScript) if err != nil { t.Fatalf("failed to start the http server in VM via systemctl with err: %v, stderr: %s", err, setupOut.Stderr) } // Wait until the http server is ready time.Sleep(5 * time.Second) - liveCheckOut, liveCheckErr := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", `curl "http://localhost:8000/data"`) + liveCheckOut, liveCheckErr := gce.RunRemotely(ctx, logger, vm, "", `curl "http://localhost:8000/data"`) if liveCheckErr != nil || strings.Contains(liveCheckOut.Stderr, "Connection refused") { t.Fatalf("Http server failed to start with stdout %s and stderr %s", liveCheckOut.Stdout, liveCheckOut.Stderr) } // 3. Config and start the agent - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, opsAgentConfig); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, opsAgentConfig); err != nil { t.Fatal(err) } @@ -3126,7 +3135,7 @@ func testPrometheusMetrics(t *testing.T, opsAgentConfig string, testChecks []moc // assertPrometheusHistogramMetric Check if the last point of the time series is // the expected Prometheus histogram metric point -func assertPrometheusHistogramMetric(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, name string, window time.Duration, expected *distribution.Distribution) error { +func assertPrometheusHistogramMetric(ctx context.Context, logger *log.Logger, vm *gce.VM, name string, window time.Duration, expected *distribution.Distribution) error { // GCM map Prometheus histogram to cumulative distribution test := prometheusMetricTest{ MetricName: fmt.Sprintf("prometheus.googleapis.com/%s/histogram", name), @@ -3153,7 +3162,7 @@ type prometheusSummaryMetric struct { // assertPrometheusSummaryMetric checks if the last point of the time series is // the expected prometheus summary metric point -func assertPrometheusSummaryMetric(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, name string, window time.Duration, expected prometheusSummaryMetric) error { +func assertPrometheusSummaryMetric(ctx context.Context, logger *log.Logger, vm *gce.VM, name string, window time.Duration, expected prometheusSummaryMetric) error { var multiErr error // There is no direct mapping of Prometheus summary type. Instead, GCM // would store the quantiles into prometheus.googleapis.com/NAME/summary @@ -3203,9 +3212,9 @@ type prometheusMetricTest struct { // assertPrometheusMetric with a given test, wait for the metric, and then use // the latest point as the actual value and compare with the expected value -func assertPrometheusMetric(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration, test prometheusMetricTest) error { +func assertPrometheusMetric(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration, test prometheusMetricTest) error { var multiErr error - if pts, err := gce.WaitForMetric(ctx, logger.ToMainLog(), vm, test.MetricName, window, test.ExtraFilter, true); err != nil { + if pts, err := gce.WaitForMetric(ctx, logger, vm, test.MetricName, window, test.ExtraFilter, true); err != nil { multiErr = multierr.Append(multiErr, err) } else { if pts.MetricKind != test.ExpectedMetricKind { @@ -3267,11 +3276,11 @@ type fileToUpload struct { // be used to validate that the ingested metrics are collected correctly. type mockPrometheusCheck struct { fileToUpload fileToUpload - check func(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, window time.Duration) error + check func(ctx context.Context, logger *log.Logger, vm *gce.VM, window time.Duration) error } // uploadFiles upload files from fs embedded file system to vm -func uploadFiles(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, fs embed.FS, files []fileToUpload) error { +func uploadFiles(ctx context.Context, logger *log.Logger, vm *gce.VM, fs embed.FS, files []fileToUpload) error { for _, upload := range files { err := func() error { f, err := fs.Open(upload.local) @@ -3279,7 +3288,7 @@ func uploadFiles(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.V return err } defer f.Close() - err = gce.UploadContent(ctx, logger.ToMainLog(), vm, f, upload.remote) + err = gce.UploadContent(ctx, logger, vm, f, upload.remote) return err }() if err != nil { @@ -3294,7 +3303,7 @@ func TestExcludeMetrics(t *testing.T) { gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) excludeConfig := `logging: receivers: @@ -3324,7 +3333,7 @@ metrics: processors: [metrics_filter] ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, excludeConfig); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, excludeConfig); err != nil { t.Fatal(err) } @@ -3337,10 +3346,10 @@ metrics: excludedMetric := "agent.googleapis.com/processes/cpu_time" window := time.Minute - if _, err := gce.WaitForMetric(ctx, logger.ToMainLog(), vm, existingMetric, window, nil, false); err != nil { + if _, err := gce.WaitForMetric(ctx, logger, vm, existingMetric, window, nil, false); err != nil { t.Error(err) } - if err := gce.AssertMetricMissing(ctx, logger.ToMainLog(), vm, excludedMetric, false, window); err != nil { + if err := gce.AssertMetricMissing(ctx, logger, vm, excludedMetric, false, window); err != nil { t.Error(err) } }) @@ -3405,30 +3414,30 @@ func terminateProcess(ctx context.Context, logger *log.Logger, vm *gce.VM, proce return nil } -func testAgentCrashRestart(ctx context.Context, t *testing.T, logger *logging.DirectoryLogger, vm *gce.VM, processNames []string, livenessChecker func(context.Context, *log.Logger, *gce.VM) error) { - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { +func testAgentCrashRestart(ctx context.Context, t *testing.T, logger *log.Logger, vm *gce.VM, processNames []string, livenessChecker func(context.Context, *log.Logger, *gce.VM) error) { + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } - pidOutputBefore, processName, err := fetchPIDAndProcessName(ctx, logger.ToMainLog(), vm, processNames) + pidOutputBefore, processName, err := fetchPIDAndProcessName(ctx, logger, vm, processNames) if err != nil { t.Fatal(err) } - logger.ToMainLog().Printf("testAgentCrashRestart: Found %s", processName) + logger.Printf("testAgentCrashRestart: Found %s", processName) // Simulate a crash. - if err := terminateProcess(ctx, logger.ToMainLog(), vm, processName); err != nil { + if err := terminateProcess(ctx, logger, vm, processName); err != nil { t.Fatal(err) } - if err := livenessChecker(ctx, logger.ToMainLog(), vm); err != nil { + if err := livenessChecker(ctx, logger, vm); err != nil { t.Fatalf("Liveness checker reported error: %v", err) } // Consistency check: make sure that the agent's PID actually changed so that // we know we crashed it successfully. - pidOutputAfter, err := fetchPID(ctx, logger.ToMainLog(), vm, processName) + pidOutputAfter, err := fetchPID(ctx, logger, vm, processName) if err != nil { t.Fatal(err) } @@ -3451,7 +3460,7 @@ func TestMetricsAgentCrashRestart(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) testAgentCrashRestart(ctx, t, logger, vm, metricsAgentProcessNamesForPlatform(vm.Platform), metricsLivenessChecker) }) @@ -3470,7 +3479,7 @@ func TestLoggingAgentCrashRestart(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) testAgentCrashRestart(ctx, t, logger, vm, []string{"fluent-bit"}, loggingLivenessChecker) }) @@ -3480,18 +3489,18 @@ func TestLoggingSelfLogs(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "ops-agent-fluent-bit", time.Hour, `severity="INFO"`); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "ops-agent-fluent-bit", time.Hour, `severity="INFO"`); err != nil { t.Error(err) } query := fmt.Sprintf(`severity="INFO" AND labels."agent.googleapis.com/health/agentKind"="ops-agent" AND labels."agent.googleapis.com/health/agentVersion"=~"^\d+\.\d+\.\d+.*$" AND labels."agent.googleapis.com/health/schemaVersion"="v1"`) - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "ops-agent-health", time.Hour, query); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "ops-agent-health", time.Hour, query); err != nil { t.Error(err) } }) @@ -3510,7 +3519,7 @@ func TestDiagnosticsCrashRestart(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) testAgentCrashRestart(ctx, t, logger, vm, diagnosticsProcessNamesForPlatform(vm.Platform), diagnosticsLivenessChecker) }) @@ -3523,15 +3532,15 @@ func testWindowsStandaloneAgentConflict(t *testing.T, installStandalone func(ctx if !gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) // 1. Install the standalone agent. - if err := installStandalone(ctx, logger.ToMainLog(), vm); err != nil { + if err := installStandalone(ctx, logger, vm); err != nil { t.Fatal(err) } // 2. Install the Ops Agent. Installation will succeed but log an error. - if err := agents.InstallOpsAgent(ctx, logger.ToMainLog(), vm, agents.LocationFromEnvVars()); err != nil { + if err := agents.InstallOpsAgent(ctx, logger, vm, agents.LocationFromEnvVars()); err != nil { t.Fatal(err) } @@ -3540,7 +3549,7 @@ func testWindowsStandaloneAgentConflict(t *testing.T, installStandalone func(ctx LogName = 'Application' ProviderName = 'google-cloud-ops-agent' } | Select-Object -ExpandProperty Message` - out, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", getEvents) + out, err := gce.RunRemotely(ctx, logger, vm, "", getEvents) if err != nil { t.Fatal(err) } @@ -3571,10 +3580,10 @@ func TestUpgradeOpsAgent(t *testing.T) { gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) // This will install the stable Ops Agent (REPO_SUFFIX=""). - if err := agents.SetupOpsAgentFrom(ctx, logger.ToMainLog(), vm, "", agents.PackageLocation{}); err != nil { + if err := agents.SetupOpsAgentFrom(ctx, logger, vm, "", agents.PackageLocation{}); err != nil { // Installation from stable may fail before the first release on // a new platform. if strings.HasPrefix(err.Error(), "InstallOpsAgent() failed to run googet") || @@ -3585,18 +3594,18 @@ func TestUpgradeOpsAgent(t *testing.T) { } // Wait for the Ops Agent to be active. Make sure that it is working. - if err := opsAgentLivenessChecker(ctx, logger.ToMainLog(), vm); err != nil { + if err := opsAgentLivenessChecker(ctx, logger, vm); err != nil { t.Fatal(err) } // Install the Ops agent from AGENT_PACKAGES_IN_GCS or REPO_SUFFIX. secondVersion := agents.LocationFromEnvVars() - if err := agents.SetupOpsAgentFrom(ctx, logger.ToMainLog(), vm, "", secondVersion); err != nil { + if err := agents.SetupOpsAgentFrom(ctx, logger, vm, "", secondVersion); err != nil { t.Fatal(err) } // Make sure that the newly installed Ops Agent is working. - if err := opsAgentLivenessChecker(ctx, logger.ToMainLog(), vm); err != nil { + if err := opsAgentLivenessChecker(ctx, logger, vm); err != nil { t.Fatal(err) } }) @@ -3606,7 +3615,7 @@ func TestResourceDetectorOnGCE(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) actual, err := runResourceDetectorCli(ctx, logger, vm) if err != nil { @@ -3654,7 +3663,7 @@ func TestResourceDetectorOnGCE(t *testing.T) { // runResourceDetectorCli uploads the resource detector runner and sets up the // env in the VM. Then run the runner to print out the JSON formatted // GCEResource and finally unmarshal it back to an instance of GCEResource -func runResourceDetectorCli(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM) (*resourcedetector.GCEResource, error) { +func runResourceDetectorCli(ctx context.Context, logger *log.Logger, vm *gce.VM) (*resourcedetector.GCEResource, error) { // Update the resourcedetector package and the go.mod and go.sum // So that the main function can locate the package from the work directory filesToUpload := []struct { @@ -3688,7 +3697,7 @@ func runResourceDetectorCli(ctx context.Context, logger *logging.DirectoryLogger return nil, err } defer f.Close() - err = gce.UploadContent(ctx, logger.ToMainLog(), vm, f, path.Join(workDir, file.remote)) + err = gce.UploadContent(ctx, logger, vm, f, path.Join(workDir, file.remote)) if err != nil { return nil, err } @@ -3727,7 +3736,7 @@ func unmarshalResource(in string) (*resourcedetector.GCEResource, error) { // installGolang downloads and setup go, and return the required command to set // the PATH before calling `go` as goPath -func installGolang(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM) error { +func installGolang(ctx context.Context, logger *log.Logger, vm *gce.VM) error { // TODO: use runtime.Version() to extract the go version goVersion := "1.19" goArch := "amd64" @@ -3743,12 +3752,11 @@ func installGolang(ctx context.Context, logger *logging.DirectoryLogger, vm *gce Start-Process msiexec.exe -ArgumentList "/i","golang.msi","/quiet" -Wait `, goVersion, goArch) } else { installCmd = fmt.Sprintf(` - set -e gsutil cp \ "gs://stackdriver-test-143416-go-install/go%s.linux-%s.tar.gz" - | \ tar --directory /usr/local -xzf /dev/stdin`, goVersion, goArch) } - _, err := gce.RunScriptRemotely(ctx, logger, vm, installCmd, nil, nil) + _, err := gce.RunRemotely(ctx, logger, vm, "", installCmd) return err } @@ -3759,12 +3767,12 @@ func goPathCommandForPlatform(platform string) string { return "export PATH=/usr/local/go/bin:$PATH" } -func runGoCode(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, content io.Reader) error { +func runGoCode(ctx context.Context, logger *log.Logger, vm *gce.VM, content io.Reader) error { workDir := path.Join(workDirForPlatform(vm.Platform), "gocode") if err := makeDirectory(ctx, logger, vm, workDir); err != nil { return err } - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, content, path.Join(workDir, "main.go")); err != nil { + if err := gce.UploadContent(ctx, logger, vm, content, path.Join(workDir, "main.go")); err != nil { return err } goInitAndRun := fmt.Sprintf(` @@ -3781,7 +3789,7 @@ func TestOTLPMetricsGCM(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) otlpConfig := ` combined: receivers: @@ -3799,7 +3807,7 @@ traces: service: pipelines: ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, otlpConfig); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, otlpConfig); err != nil { t.Fatal(err) } @@ -3830,7 +3838,7 @@ traces: "workload.googleapis.com/WORKLOAD.GOOGLEAPIS.COM/otlp.test.prefix4", "workload.googleapis.com/WORKLOAD.googleapis.com/otlp.test.prefix5", } { - if _, err = gce.WaitForMetric(ctx, logger.ToMainLog(), vm, name, time.Hour, nil, false); err != nil { + if _, err = gce.WaitForMetric(ctx, logger, vm, name, time.Hour, nil, false); err != nil { t.Error(err) } } @@ -3868,7 +3876,7 @@ traces: }, } - series, err := gce.WaitForMetricSeries(ctx, logger.ToMainLog(), vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", time.Hour, nil, false, len(expectedFeatures)) + series, err := gce.WaitForMetricSeries(ctx, logger, vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", time.Hour, nil, false, len(expectedFeatures)) if err != nil { t.Error(err) return @@ -3886,7 +3894,7 @@ func TestOTLPMetricsGMP(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) otlpConfig := ` combined: receivers: @@ -3903,7 +3911,7 @@ traces: service: pipelines: ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, otlpConfig); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, otlpConfig); err != nil { t.Fatal(err) } @@ -3934,7 +3942,7 @@ traces: "prometheus.googleapis.com/WORKLOAD_GOOGLEAPIS_COM_otlp_test_prefix4/gauge", "prometheus.googleapis.com/WORKLOAD_googleapis_com_otlp_test_prefix5/gauge", } { - if _, err = gce.WaitForMetric(ctx, logger.ToMainLog(), vm, name, time.Hour, nil, true); err != nil { + if _, err = gce.WaitForMetric(ctx, logger, vm, name, time.Hour, nil, true); err != nil { t.Error(err) } } @@ -3966,7 +3974,7 @@ traces: }, } - series, err := gce.WaitForMetricSeries(ctx, logger.ToMainLog(), vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", time.Hour, nil, false, len(expectedFeatures)) + series, err := gce.WaitForMetricSeries(ctx, logger, vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", time.Hour, nil, false, len(expectedFeatures)) if err != nil { t.Error(err) return @@ -3984,7 +3992,7 @@ func TestOTLPTraces(t *testing.T) { t.Parallel() gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) otlpConfig := ` combined: receivers: @@ -4000,7 +4008,7 @@ metrics: service: pipelines: ` - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, otlpConfig); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, otlpConfig); err != nil { t.Fatal(err) } @@ -4017,7 +4025,7 @@ metrics: t.Fatal(err) } - if _, err := gce.WaitForTrace(ctx, logger.ToMainLog(), vm, time.Hour); err != nil { + if _, err := gce.WaitForTrace(ctx, logger, vm, time.Hour); err != nil { t.Error(err) } }) @@ -4079,7 +4087,8 @@ func TestPortsAndAPIHealthChecks(t *testing.T) { "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/devstorage.read_write", }, ",") - ctx, logger, vm := agents.CommonSetupWithExtraCreateArguments(t, platform, []string{"--scopes", customScopes}) + ctx, dirLog, vm := agents.CommonSetupWithExtraCreateArguments(t, platform, []string{"--scopes", customScopes}) + logger := dirLog.ToMainLog() if !gce.IsWindows(vm.Platform) { var packages []string @@ -4088,23 +4097,23 @@ func TestPortsAndAPIHealthChecks(t *testing.T) { } else { packages = []string{"netcat"} } - err := agents.InstallPackages(ctx, logger.ToMainLog(), vm, packages) + err := agents.InstallPackages(ctx, logger, vm, packages) if err != nil { t.Fatalf("failed to install %v with err: %s", packages, err) } } - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", listenToPortForPlatform(vm.Platform)); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", listenToPortForPlatform(vm.Platform)); err != nil { t.Fatal(err) } // Wait for port to be in listen mode. time.Sleep(30 * time.Second) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } - cmdOut, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", getRecentServiceOutputForPlatform(vm.Platform)) + cmdOut, err := gce.RunRemotely(ctx, logger, vm, "", getRecentServiceOutputForPlatform(vm.Platform)) if err != nil { t.Fatal(err) } @@ -4114,7 +4123,7 @@ func TestPortsAndAPIHealthChecks(t *testing.T) { checkExpectedHealthCheckResult(t, cmdOut.Stdout, "API", "FAIL", "MonApiScopeErr") query := fmt.Sprintf(`severity="ERROR" AND jsonPayload.code="MonApiScopeErr" AND labels."agent.googleapis.com/health/agentKind"="ops-agent" AND labels."agent.googleapis.com/health/agentVersion"=~"^\d+\.\d+\.\d+.*$" AND labels."agent.googleapis.com/health/schemaVersion"="v1"`) - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "ops-agent-health", time.Hour, query); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "ops-agent-health", time.Hour, query); err != nil { t.Error(err) } }) @@ -4128,13 +4137,13 @@ func TestNetworkHealthCheck(t *testing.T) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } - cmdOut, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", getRecentServiceOutputForPlatform(vm.Platform)) + cmdOut, err := gce.RunRemotely(ctx, logger, vm, "", getRecentServiceOutputForPlatform(vm.Platform)) if err != nil { t.Fatal(err) } @@ -4143,21 +4152,21 @@ func TestNetworkHealthCheck(t *testing.T) { checkExpectedHealthCheckResult(t, cmdOut.Stdout, "Ports", "PASS", "") checkExpectedHealthCheckResult(t, cmdOut.Stdout, "API", "PASS", "") - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", stopCommandForPlatform(vm.Platform)); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", stopCommandForPlatform(vm.Platform)); err != nil { t.Fatal(err) } // Setting deny egress firewall rule. Waiting to changes to propagate - if _, err := gce.AddTagToVm(ctx, logger.ToMainLog(), vm, []string{gce.DenyEgressTrafficTag}); err != nil { + if _, err := gce.AddTagToVm(ctx, logger, vm, []string{gce.DenyEgressTrafficTag}); err != nil { t.Fatal(err) } time.Sleep(time.Minute) - if _, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", startCommandForPlatform(vm.Platform)); err != nil { + if _, err := gce.RunRemotely(ctx, logger, vm, "", startCommandForPlatform(vm.Platform)); err != nil { t.Fatal(err) } - cmdOut, err = gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", getRecentServiceOutputForPlatform(vm.Platform)) + cmdOut, err = gce.RunRemotely(ctx, logger, vm, "", getRecentServiceOutputForPlatform(vm.Platform)) if err != nil { t.Fatal(err) } @@ -4180,7 +4189,7 @@ func TestParsingFailureCheck(t *testing.T) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetup(t, platform) + ctx, logger, vm := setupMainLogAndVM(t, platform) logPath := logPathForPlatform(vm.Platform) config := fmt.Sprintf(`logging: @@ -4202,17 +4211,17 @@ func TestParsingFailureCheck(t *testing.T) { processors: [json1] `, logPath, "%Y-%m-%dT%H:%M:.%L%z") - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } line := fmt.Sprintf(`{"log":"{\"level\":\"info\",\"message\":\"start\"}\n","time":"%s"}`, time.Now().UTC().Format(time.RFC3339Nano)) + "\n" - if err := gce.UploadContent(ctx, logger.ToMainLog(), vm, strings.NewReader(line), logPath); err != nil { + if err := gce.UploadContent(ctx, logger, vm, strings.NewReader(line), logPath); err != nil { t.Fatalf("error writing dummy log line: %v", err) } query := fmt.Sprintf(`severity="ERROR" AND jsonPayload.code="LogParseErr" AND labels."agent.googleapis.com/health/agentKind"="ops-agent" AND labels."agent.googleapis.com/health/agentVersion"=~"^\d+\.\d+\.\d+.*$" AND labels."agent.googleapis.com/health/schemaVersion"="v1"`) - if err := gce.WaitForLog(ctx, logger.ToMainLog(), vm, "ops-agent-health", time.Hour, query); err != nil { + if err := gce.WaitForLog(ctx, logger, vm, "ops-agent-health", time.Hour, query); err != nil { t.Error(err) } @@ -4226,7 +4235,9 @@ func TestBufferLimitSizeOpsAgent(t *testing.T) { if gce.IsWindows(platform) { t.SkipNow() } - ctx, logger, vm := agents.CommonSetupWithExtraCreateArguments(t, platform, []string{"--boot-disk-size", "100G"}) + ctx, dirLog, vm := agents.CommonSetupWithExtraCreateArguments(t, platform, []string{"--boot-disk-size", "100G"}) + logger := dirLog.ToMainLog() + logPath := logPathForPlatform(vm.Platform) logsPerSecond := 100000 config := fmt.Sprintf(`logging: @@ -4243,7 +4254,7 @@ func TestBufferLimitSizeOpsAgent(t *testing.T) { receivers: [log_syslog] processors: []`, logPath) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, config); err != nil { + if err := agents.SetupOpsAgent(ctx, logger, vm, config); err != nil { t.Fatal(err) } var bufferDir string @@ -4273,7 +4284,7 @@ func TestBufferLimitSizeOpsAgent(t *testing.T) { done du -c %s | cut -f 1 | tail -n 1`, logPath, logsPerSecond, logPath, bufferDir) - if _, err := gce.AddTagToVm(ctx, logger.ToFile("firewall_setup.txt"), vm, []string{gce.DenyEgressTrafficTag}); err != nil { + if _, err := gce.AddTagToVm(ctx, dirLog.ToFile("firewall_setup.txt"), vm, []string{gce.DenyEgressTrafficTag}); err != nil { t.Fatal(err) } @@ -4294,7 +4305,7 @@ func TestBufferLimitSizeOpsAgent(t *testing.T) { t.Fatalf("%d is greater than the allowed threshold %d", byteCount, threshold) } - if _, err := gce.RemoveTagFromVm(ctx, logger.ToFile("firewall_setup.txt"), vm, []string{gce.DenyEgressTrafficTag}); err != nil { + if _, err := gce.RemoveTagFromVm(ctx, dirLog.ToFile("firewall_setup.txt"), vm, []string{gce.DenyEgressTrafficTag}); err != nil { t.Fatal(err) } @@ -4309,13 +4320,13 @@ func TestNoNvmlOtelReceiverWithoutGpu(t *testing.T) { gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + ctx, logger, vm := setupMainLogAndVM(t, platform) + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } time.Sleep(60 * time.Second) - _, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, "syslog", time.Hour, `jsonPayload.message=~"Nvidia|nvml"`, 5) + _, err := gce.QueryLog(ctx, logger, vm, "syslog", time.Hour, `jsonPayload.message=~"Nvidia|nvml"`, 5) if err == nil { t.Error("expected no logs to contain Nvidia or nvml when the instance has no gpu") } else if !strings.Contains(err.Error(), "not found, exhausted retries") { @@ -4329,12 +4340,14 @@ func TestRestartVM(t *testing.T) { gce.RunForEachPlatform(t, func(t *testing.T, platform string) { t.Parallel() - ctx, logger, vm := agents.CommonSetup(t, platform) - if err := agents.SetupOpsAgent(ctx, logger.ToMainLog(), vm, ""); err != nil { + ctx, dirLog, vm := agents.CommonSetup(t, platform) + logger := dirLog.ToMainLog() + + if err := agents.SetupOpsAgent(ctx, logger, vm, ""); err != nil { t.Fatal(err) } - cmdOut, err := gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", getRecentServiceOutputForPlatform(vm.Platform)) + cmdOut, err := gce.RunRemotely(ctx, logger, vm, "", getRecentServiceOutputForPlatform(vm.Platform)) if err != nil { t.Fatal(err) } @@ -4344,11 +4357,12 @@ func TestRestartVM(t *testing.T) { checkExpectedHealthCheckResult(t, cmdOut.Stdout, "Ports", "PASS", "") checkExpectedHealthCheckResult(t, cmdOut.Stdout, "API", "PASS", "") - if err := gce.RestartInstance(ctx, logger.ToFile("VM_restart.txt"), vm); err != nil { + logger.Printf(`Restarting instance. For details, see "VM_restart.txt".`) + if err := gce.RestartInstance(ctx, dirLog.ToFile("VM_restart.txt"), vm); err != nil { t.Fatal(err) } - cmdOut, err = gce.RunRemotely(ctx, logger.ToMainLog(), vm, "", getRecentServiceOutputForPlatform(vm.Platform)) + cmdOut, err = gce.RunRemotely(ctx, logger, vm, "", getRecentServiceOutputForPlatform(vm.Platform)) if err != nil { t.Fatal(err) } diff --git a/integration_test/third_party_apps_test.go b/integration_test/third_party_apps_test.go index e064f540fe..e259266ec9 100644 --- a/integration_test/third_party_apps_test.go +++ b/integration_test/third_party_apps_test.go @@ -86,7 +86,7 @@ func removeFromSlice(original []string, toRemove string) []string { } // assertFilePresence returns an error if the provided file path doesn't exist on the VM. -func assertFilePresence(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, filePath string) error { +func assertFilePresence(ctx context.Context, logger *log.Logger, vm *gce.VM, filePath string) error { var fileQuery string if gce.IsWindows(vm.Platform) { fileQuery = fmt.Sprintf(`Test-Path -Path "%s"`, filePath) @@ -94,7 +94,7 @@ func assertFilePresence(ctx context.Context, logger *logging.DirectoryLogger, vm fileQuery = fmt.Sprintf(`sudo test -f %s`, filePath) } - out, err := gce.RunScriptRemotely(ctx, logger, vm, fileQuery, nil, nil) + out, err := gce.RunRemotely(ctx, logger, vm, "", fileQuery) if err != nil { return fmt.Errorf("error accessing backup file: %v", err) } @@ -138,7 +138,7 @@ func readFileFromScriptsDir(scriptPath string) ([]byte, error) { // The scriptPath should be relative to SCRIPTS_DIR. // The script should be a shell script for a Linux VM and powershell for a Windows VM. // env is a map containing environment variables to provide to the script as it runs. -func runScriptFromScriptsDir(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, scriptPath string, env map[string]string) (gce.CommandOutput, error) { +func runScriptFromScriptsDir(ctx context.Context, logger *log.Logger, vm *gce.VM, scriptPath string, env map[string]string) (gce.CommandOutput, error) { logger.ToMainLog().Printf("Running script with path %s", scriptPath) scriptContents, err := readFileFromScriptsDir(scriptPath) @@ -419,7 +419,7 @@ func stripUnavailableFields(fields []*metadata.LogFields, platform string) []*me return result } -func runLoggingTestCases(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, logs []*metadata.ExpectedLog) error { +func runLoggingTestCases(ctx context.Context, logger *log.Logger, vm *gce.VM, logs []*metadata.ExpectedLog) error { // Wait for each entry in LogEntries concurrently. This is especially helpful // when the assertions fail: we don't want to wait for each one to time out // back-to-back. @@ -444,7 +444,7 @@ func runLoggingTestCases(ctx context.Context, logger *logging.DirectoryLogger, v query := constructQuery(entry.LogName, entry.Fields) // Query logging backend for log matching the query. - actualLog, err := gce.QueryLog(ctx, logger.ToMainLog(), vm, entry.LogName, 1*time.Hour, query, gce.QueryMaxAttempts) + actualLog, err := gce.QueryLog(ctx, logger, vm, entry.LogName, 1*time.Hour, query, gce.QueryMaxAttempts) if err != nil { c <- err return @@ -466,9 +466,9 @@ func runLoggingTestCases(ctx context.Context, logger *logging.DirectoryLogger, v return err } -func runMetricsTestCases(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, metrics []*metadata.ExpectedMetric, fc *feature_tracking_metadata.FeatureTrackingContainer) error { +func runMetricsTestCases(ctx context.Context, logger *log.Logger, vm *gce.VM, metrics []*metadata.ExpectedMetric, fc *feature_tracking_metadata.FeatureTrackingContainer) error { var err error - logger.ToMainLog().Printf("Parsed expectedMetrics: %s", util.DumpPointerArray(metrics, "%+v")) + logger.Printf("Parsed expectedMetrics: %s", util.DumpPointerArray(metrics, "%+v")) // Wait for the representative metric first, which is intended to *always* // be sent. If it doesn't exist, we fail fast and skip running the other metrics; // if it does exist, we go on to the other metrics in parallel, by which point they @@ -488,7 +488,7 @@ func runMetricsTestCases(ctx context.Context, logger *logging.DirectoryLogger, v } // Give some catch-up time to the remaining metrics, which tend to be configured // for a 60-second interval, plus 10 seconds to let the data propagate in the backend. - logger.ToMainLog().Println("Found representative metric, sleeping before checking remaining metrics") + logger.Println("Found representative metric, sleeping before checking remaining metrics") time.Sleep(70 * time.Second) // Wait for all remaining metrics, skipping the optional ones. // TODO: Improve coverage for optional metrics. @@ -496,11 +496,11 @@ func runMetricsTestCases(ctx context.Context, logger *logging.DirectoryLogger, v var requiredMetrics []*metadata.ExpectedMetric for _, metric := range metrics { if metric.Optional || metric.Representative { - logger.ToMainLog().Printf("Skipping optional or representative metric %s", metric.Type) + logger.Printf("Skipping optional or representative metric %s", metric.Type) continue } if metadata.SliceContains(metric.UnavailableOn, vm.Platform) { - logger.ToMainLog().Printf("Skipping metric %s due to unavailable_on", metric.Type) + logger.Printf("Skipping metric %s due to unavailable_on", metric.Type) continue } requiredMetrics = append(requiredMetrics, metric) @@ -517,11 +517,11 @@ func runMetricsTestCases(ctx context.Context, logger *logging.DirectoryLogger, v } if fc == nil { - logger.ToMainLog().Printf("skipping feature tracking integration tests") + logger.Printf("skipping feature tracking integration tests") return err } - series, ft_err := gce.WaitForMetricSeries(ctx, logger.ToMainLog(), vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", 1*time.Hour, nil, false, len(fc.Features)) + series, ft_err := gce.WaitForMetricSeries(ctx, logger, vm, "agent.googleapis.com/agent/internal/ops/feature_tracking", 1*time.Hour, nil, false, len(fc.Features)) if ft_err != nil { return multierr.Append(err, ft_err) } @@ -529,8 +529,8 @@ func runMetricsTestCases(ctx context.Context, logger *logging.DirectoryLogger, v return multierr.Append(err, feature_tracking_metadata.AssertFeatureTrackingMetrics(series, fc.Features)) } -func assertMetric(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, metric *metadata.ExpectedMetric) error { - series, err := gce.WaitForMetric(ctx, logger.ToMainLog(), vm, metric.Type, 1*time.Hour, nil, false) +func assertMetric(ctx context.Context, logger *log.Logger, vm *gce.VM, metric *metadata.ExpectedMetric) error { + series, err := gce.WaitForMetric(ctx, logger, vm, metric.Type, 1*time.Hour, nil, false) if err != nil { // Optional metrics can be missing if metric.Optional && gce.IsExhaustedRetriesMetricError(err) { @@ -562,7 +562,7 @@ func runSingleTest(ctx context.Context, logger *logging.DirectoryLogger, vm *gce } if _, err = runScriptFromScriptsDir( - ctx, logger, vm, path.Join("applications", app, folder, "install"), installEnv); err != nil { + ctx, logger.ToMainLog(), vm, path.Join("applications", app, folder, "install"), installEnv); err != nil { return retryable, fmt.Errorf("error installing %s: %v", app, err) } @@ -589,12 +589,12 @@ func runSingleTest(ctx context.Context, logger *logging.DirectoryLogger, vm *gce return nonRetryable, fmt.Errorf("error installing agent: %v", err) } - if _, err = runScriptFromScriptsDir(ctx, logger, vm, path.Join("applications", app, "enable"), nil); err != nil { + if _, err = runScriptFromScriptsDir(ctx, logger.ToMainLog(), vm, path.Join("applications", app, "enable"), nil); err != nil { return nonRetryable, fmt.Errorf("error enabling %s: %v", app, err) } backupConfigFilePath := util.ConfigPathForPlatform(vm.Platform) + ".bak" - if err = assertFilePresence(ctx, logger, vm, backupConfigFilePath); err != nil { + if err = assertFilePresence(ctx, logger.ToMainLog(), vm, backupConfigFilePath); err != nil { return nonRetryable, fmt.Errorf("error when fetching back up config file %s: %v", backupConfigFilePath, err) } @@ -602,7 +602,7 @@ func runSingleTest(ctx context.Context, logger *logging.DirectoryLogger, vm *gce exerciseScript := path.Join("applications", app, "exercise") if _, err := readFileFromScriptsDir(exerciseScript); err == nil { logger.ToMainLog().Println("exercise script found, running...") - if _, err = runScriptFromScriptsDir(ctx, logger, vm, exerciseScript, nil); err != nil { + if _, err = runScriptFromScriptsDir(ctx, logger.ToMainLog(), vm, exerciseScript, nil); err != nil { return nonRetryable, fmt.Errorf("error exercising %s: %v", app, err) } } @@ -612,7 +612,7 @@ func runSingleTest(ctx context.Context, logger *logging.DirectoryLogger, vm *gce // TODO(b/254325217): bad bad bad, remove this horrible hack once we fix Aerospike on SLES if app == AerospikeApp && folder == "sles" { logger.ToMainLog().Printf("skipping aerospike logging tests (b/254325217)") - } else if err = runLoggingTestCases(ctx, logger, vm, metadata.ExpectedLogs); err != nil { + } else if err = runLoggingTestCases(ctx, logger.ToMainLog(), vm, metadata.ExpectedLogs); err != nil { return nonRetryable, err } } @@ -645,7 +645,7 @@ func runSingleTest(ctx context.Context, logger *logging.DirectoryLogger, vm *gce fc, err := getExpectedFeatures(app) - if err = runMetricsTestCases(ctx, logger, vm, metadata.ExpectedMetrics, fc); err != nil { + if err = runMetricsTestCases(ctx, logger.ToMainLog(), vm, metadata.ExpectedMetrics, fc); err != nil { return nonRetryable, err } } From 00ed61326be324d7261f3b7a5ecd929913ddaf12 Mon Sep 17 00:00:00 2001 From: Martijn van Schaardenburg Date: Tue, 7 Nov 2023 19:02:40 +0000 Subject: [PATCH 2/5] fix compile error, add comment --- integration_test/gce/gce_testing.go | 2 ++ integration_test/third_party_apps_test.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/integration_test/gce/gce_testing.go b/integration_test/gce/gce_testing.go index e36b2e0135..fc24c1cf6d 100644 --- a/integration_test/gce/gce_testing.go +++ b/integration_test/gce/gce_testing.go @@ -1802,6 +1802,8 @@ func logLocation(logRootDir, testName string) string { // t.Name() inside the directory TEST_UNDECLARED_OUTPUTS_DIR. // If creating the logger fails, it will abort the test. // At the end of the test, the logger will be cleaned up. +// TODO: Move this function along with logLocation() into the logging package, +// since nothing else in this file depends on DirectoryLogger anymore. func SetupLogger(t *testing.T) *logging.DirectoryLogger { t.Helper() name := strings.Replace(t.Name(), "/", "_", -1) diff --git a/integration_test/third_party_apps_test.go b/integration_test/third_party_apps_test.go index e259266ec9..f6e4239364 100644 --- a/integration_test/third_party_apps_test.go +++ b/integration_test/third_party_apps_test.go @@ -139,7 +139,7 @@ func readFileFromScriptsDir(scriptPath string) ([]byte, error) { // The script should be a shell script for a Linux VM and powershell for a Windows VM. // env is a map containing environment variables to provide to the script as it runs. func runScriptFromScriptsDir(ctx context.Context, logger *log.Logger, vm *gce.VM, scriptPath string, env map[string]string) (gce.CommandOutput, error) { - logger.ToMainLog().Printf("Running script with path %s", scriptPath) + logger.Printf("Running script with path %s", scriptPath) scriptContents, err := readFileFromScriptsDir(scriptPath) if err != nil { From a80714624783087951593b08636a5481dc19d930 Mon Sep 17 00:00:00 2001 From: Martijn van Schaardenburg Date: Tue, 7 Nov 2023 19:17:02 +0000 Subject: [PATCH 3/5] add some sudos --- integration_test/ops_agent_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration_test/ops_agent_test.go b/integration_test/ops_agent_test.go index ca13c1e7c2..a8cdf5de40 100644 --- a/integration_test/ops_agent_test.go +++ b/integration_test/ops_agent_test.go @@ -155,7 +155,7 @@ func makeDirectory(ctx context.Context, logger *log.Logger, vm *gce.VM, director if gce.IsWindows(vm.Platform) { createFolderCmd = fmt.Sprintf("New-Item -ItemType Directory -Path %s", directory) } else { - createFolderCmd = fmt.Sprintf("mkdir -p %s", directory) + createFolderCmd = fmt.Sprintf("sudo mkdir -p %s", directory) } _, err := gce.RunRemotely(ctx, logger, vm, "", createFolderCmd) return err @@ -3754,7 +3754,7 @@ func installGolang(ctx context.Context, logger *log.Logger, vm *gce.VM) error { installCmd = fmt.Sprintf(` gsutil cp \ "gs://stackdriver-test-143416-go-install/go%s.linux-%s.tar.gz" - | \ - tar --directory /usr/local -xzf /dev/stdin`, goVersion, goArch) + sudo tar --directory /usr/local -xzf /dev/stdin`, goVersion, goArch) } _, err := gce.RunRemotely(ctx, logger, vm, "", installCmd) return err From 16061886e1178af9906541521fb911a426cfaab0 Mon Sep 17 00:00:00 2001 From: Martijn van Schaardenburg Date: Tue, 14 Nov 2023 11:11:48 -0500 Subject: [PATCH 4/5] change todo --- integration_test/gce/gce_testing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test/gce/gce_testing.go b/integration_test/gce/gce_testing.go index d1214694bd..32811259e0 100644 --- a/integration_test/gce/gce_testing.go +++ b/integration_test/gce/gce_testing.go @@ -1802,7 +1802,7 @@ func logLocation(logRootDir, testName string) string { // t.Name() inside the directory TEST_UNDECLARED_OUTPUTS_DIR. // If creating the logger fails, it will abort the test. // At the end of the test, the logger will be cleaned up. -// TODO: Move this function along with logLocation() into the logging package, +// TODO: Move this function along with logLocation() into the agents package, // since nothing else in this file depends on DirectoryLogger anymore. func SetupLogger(t *testing.T) *logging.DirectoryLogger { t.Helper() From 7d24a90ffdc1e4ad7403e3f130143aa5a2aca600 Mon Sep 17 00:00:00 2001 From: Martijn van Schaardenburg Date: Mon, 20 Nov 2023 14:27:15 -0500 Subject: [PATCH 5/5] fix logger type in buildGoBinary --- integration_test/ops_agent_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test/ops_agent_test.go b/integration_test/ops_agent_test.go index fdacc1a0cb..8474bd6326 100644 --- a/integration_test/ops_agent_test.go +++ b/integration_test/ops_agent_test.go @@ -3207,7 +3207,7 @@ func TestPrometheusSummaryMetrics(t *testing.T) { testPrometheusMetrics(t, config, testChecks) } -func buildGoBinary(ctx context.Context, logger *logging.DirectoryLogger, vm *gce.VM, source, dest string) error { +func buildGoBinary(ctx context.Context, logger *log.Logger, vm *gce.VM, source, dest string) error { installCmd := fmt.Sprintf(` /usr/local/go/bin/go build -o %s/ %s`, dest, source) _, err := gce.RunScriptRemotely(ctx, logger, vm, installCmd, nil, nil)