-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
⭐️ new panic handler that reports client panics (#2963)
* ⭐️ new panic handler that reports client panics * 🧹 use log.Error instead of lof.Info
- Loading branch information
1 parent
0e7903c
commit f264fde
Showing
5 changed files
with
638 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright (c) Mondoo, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package health | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/rs/zerolog/log" | ||
"go.mondoo.com/cnquery/v9/cli/config" | ||
"go.mondoo.com/cnquery/v9/providers-sdk/v1/upstream" | ||
"go.mondoo.com/ranger-rpc" | ||
"runtime/debug" | ||
) | ||
|
||
//go:generate protoc --proto_path=. --go_out=. --go_opt=paths=source_relative --rangerrpc_out=. errors.proto | ||
|
||
func ReportPanic(product, version, build string) { | ||
if r := recover(); r != nil { | ||
sendPanic(product, version, build, r, debug.Stack()) | ||
|
||
// output error to console | ||
panic(r) | ||
} | ||
} | ||
|
||
// sendPanic sends a panic to the mondoo platform for further analysis if the | ||
// service account is configured. | ||
// This function does not return an error as it is not critical to send the panic to the platform. | ||
func sendPanic(product, version, build string, r any, stacktrace []byte) { | ||
// 1. read config | ||
opts, err := config.Read() | ||
if err != nil { | ||
log.Error().Err(err).Msg("failed to read config") | ||
return | ||
} | ||
|
||
serviceAccount := opts.GetServiceCredential() | ||
if serviceAccount == nil { | ||
log.Error().Msg("no service account configured") | ||
return | ||
} | ||
|
||
// 2. create local support bundle | ||
event := &SendErrorReq{ | ||
ServiceAccountMrn: opts.ServiceAccountMrn, | ||
AgentMrn: opts.AgentMrn, | ||
Product: &ProductInfo{ | ||
Name: product, | ||
Version: version, | ||
Build: build, | ||
}, | ||
Error: &ErrorInfo{ | ||
Message: "panic: " + fmt.Sprintf("%v", r), | ||
Stacktrace: string(stacktrace), | ||
}, | ||
} | ||
|
||
// 3. send error to mondoo platform | ||
proxy, err := config.GetAPIProxy() | ||
if err != nil { | ||
log.Error().Err(err).Msg("failed to parse proxy setting") | ||
return | ||
} | ||
httpClient := ranger.NewHttpClient(ranger.WithProxy(proxy)) | ||
|
||
plugins := []ranger.ClientPlugin{} | ||
certAuth, err := upstream.NewServiceAccountRangerPlugin(serviceAccount) | ||
if err != nil { | ||
return | ||
} | ||
plugins = append(plugins, certAuth) | ||
|
||
cl, err := NewErrorReportingClient(serviceAccount.ApiEndpoint, httpClient, plugins...) | ||
if err != nil { | ||
log.Error().Err(err).Msg("failed to create error reporting client") | ||
return | ||
} | ||
|
||
_, err = cl.SendError(context.Background(), event) | ||
if err != nil { | ||
log.Error().Err(err).Msg("failed to send error to mondoo platform") | ||
return | ||
} | ||
|
||
log.Info().Msg("reported panic to Mondoo platform") | ||
} |
Oops, something went wrong.