Skip to content

Commit 7583b5c

Browse files
authored
Ensure agent exits if process receives SIGINT or SIGTERM signal (#100)
Ensure that the agent process exits if the process receives a `SIGINT` or `SIGTERM` signal. **Tests:** - Validate process will exit if TTY is set: - Created a new Ubuntu arm64 VM - Built agent with `make docker-build` - Ran agent in VM and sent a `Ctrl-C` signal - Confirmed agent process exited - Validate process will exit when run as daemon: - Created a new Ubuntu arm64 VM - Built agent with `make docker-build` - Added a new `.service` file - Reloaded systemd configuration with `systemctl daemon-reload` - Enabled service with `systemctl enable postman-insights-agent.service` - Confirmed successful daemon startup with `journalctl -fu postman-insights-agent.service` - Sent SIGINT signal with `kill -2 {process-id}` - Confirmed agent process exited **Logs:** *Interactive (TTY is set) logs:* ```sh dev@ubuntu-insights-agent:~$ sudo POSTMAN_API_KEY=$INSIGHTS_KEY ./postman-insights-agent apidump --project $PROJECT_ID [INFO] Telemetry unavailable; no Amplitude key configured. [INFO] This is caused by building from source rather than using an official build. [INFO] Postman Insights Agent 0.0.0 [INFO] Created new trace on Postman Cloud: akita://Test Project:trace:aquamarine-mark-f6c0e9b5 [INFO] Failed to clear VmHWM. Memory usage telemetry will report the high-water mark as computed by /proc/self/status. [INFO] Running learn mode on interfaces lo, enp0s5 [INFO] --filter flag is not set; capturing all network traffic to and from your services. [INFO] Send SIGINT (Ctrl-C) to stop... ^C[INFO] Received interrupt, stopping trace collection... [INFO] Trace collection stopped [INFO] Captured 454 TCP packets total; 301 unparsed TCP segments. No TLS headers were found, so this may represent a network protocol that the agent does not know how to parse. [ERROR] No HTTP calls captured! 🛑 ``` *Systemd daemon logs:* ```sh Mar 26 20:01:32 ubuntu-insights-agent systemd[1]: Started postman-insights-agent.service - Postman Insights Agent. Mar 26 20:01:32 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Telemetry unavailable; no Amplitude key configured. Mar 26 20:01:32 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] This is caused by building from source rather than using an official build. Mar 26 20:01:32 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Postman Insights Agent 0.0.0 Mar 26 20:01:33 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Created new trace on Postman Cloud: akita://Test Project:trace:tree-lady-44b4e9a1 Mar 26 20:01:33 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Failed to clear VmHWM. Memory usage telemetry will report the high-water mark as computed by /proc/self/status. Mar 26 20:01:33 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Running learn mode on interfaces lo, enp0s5 Mar 26 20:01:33 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] --filter flag is not set; capturing all network traffic to and from your services. Mar 26 20:01:33 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Send SIGINT (Ctrl-C) to stop... Mar 26 20:02:25 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Received interrupt, stopping trace collection... Mar 26 20:02:30 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Trace collection stopped Mar 26 20:02:30 ubuntu-insights-agent postman-insights-agent[5069]: [INFO] Captured 2 TLS handshake messages out of 6997 total TCP segments. This may mean you are trying to capture HTTPS traffic, which is currently unsupported. Mar 26 20:02:30 ubuntu-insights-agent postman-insights-agent[5069]: [ERROR] No HTTP calls captured! 🛑 Mar 26 20:02:30 ubuntu-insights-agent systemd[1]: postman-insights-agent.service: Deactivated successfully. Mar 26 20:02:30 ubuntu-insights-agent systemd[1]: postman-insights-agent.service: Consumed 1.703s CPU time, 48.1M memory peak, 0B memory swap peak. ```
1 parent db27c08 commit 7583b5c

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

apidump/apidump.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ const (
7171
notMatchedFilter filterState = "UNMATCHED"
7272
)
7373

74+
var ProcessSignalErr = errors.New("process received exit signal")
75+
7476
// Args for running apidump as daemonset in Kubernetes
7577
type DaemonsetArgs struct {
7678
TargetNetworkNamespaceOpt string
@@ -857,6 +859,8 @@ func (a *apidump) Run() error {
857859
printer.Stderr.Infof("%s\n", printer.Color.Yellow("--filter flag is not set; capturing all network traffic to and from your services."))
858860
}
859861

862+
// Lets us track if the process has received a signal like SIGINT and SIGTERM.
863+
var processReceivedSignal os.Signal
860864
// Keep track of errors by interface, as well as errors from the subcommand
861865
// if applicable.
862866
errorsByInterface := make(map[string]error)
@@ -927,8 +931,8 @@ func (a *apidump) Run() error {
927931
DoneWaitingForSignal:
928932
for {
929933
select {
930-
case received := <-sig:
931-
printer.Stderr.Infof("Received %v, stopping trace collection...\n", received.String())
934+
case processReceivedSignal = <-sig:
935+
printer.Stderr.Infof("Received %v, stopping trace collection...\n", processReceivedSignal.String())
932936
break DoneWaitingForSignal
933937
case interfaceErr := <-errChan:
934938
errorsByInterface[interfaceErr.interfaceName] = interfaceErr.err
@@ -991,9 +995,13 @@ func (a *apidump) Run() error {
991995

992996
if a.dumpSummary.IsEmpty() {
993997
telemetry.Failure("empty API trace")
994-
return errors.New("API trace is empty")
998+
} else {
999+
printer.Stderr.Infof("%s 🎉\n\n", printer.Color.Green("Success!"))
1000+
}
1001+
1002+
if processReceivedSignal != nil {
1003+
return ProcessSignalErr
9951004
}
9961005

997-
printer.Stderr.Infof("%s 🎉\n\n", printer.Color.Green("Success!"))
9981006
return nil
9991007
}

cmd/internal/apidump/apidump.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/postmanlabs/postman-insights-agent/telemetry"
1919
"github.com/postmanlabs/postman-insights-agent/util"
2020
"github.com/spf13/cobra"
21+
"golang.org/x/term"
2122
)
2223

2324
var (
@@ -95,16 +96,19 @@ func applyRandomizedStart() {
9596
// think there is a reliable way to tell the context otherwise.
9697
func apidumpRunWithoutAbnormalExit(cmd *cobra.Command, args []string) error {
9798
err := apidumpRunInternal(cmd, args)
98-
9999
if err == nil {
100100
return nil
101101
}
102102

103-
// Log the error and wait forever.
104-
printer.Stderr.Errorf("Error during initiaization: %v\n", err)
105-
printer.Stdout.Infof("This process will not exit, to avoid boot loops. Please correct the command line flags or environment and retry.\n")
103+
if !errors.Is(err, apidump.ProcessSignalErr) {
104+
printer.Stderr.Errorf("Error during initiaization: %v\n", err)
105+
if !term.IsTerminal(int(os.Stdout.Fd())) {
106+
printer.Stdout.Infof("This process will not exit, to avoid boot loops. Please correct the command line flags or environment and retry.\n")
107+
select {}
108+
}
109+
}
106110

107-
select {}
111+
return nil
108112
}
109113

110114
func apidumpRunInternal(cmd *cobra.Command, _ []string) error {

0 commit comments

Comments
 (0)