Skip to content

Commit e3fa2e9

Browse files
torsmcopybara-github
authored andcommitted
StdinService: Add local logging config option
PiperOrigin-RevId: 871839267
1 parent b39f376 commit e3fa2e9

File tree

4 files changed

+208
-40
lines changed

4 files changed

+208
-40
lines changed

fleetspeak/src/client/stdinservice/proto/fleetspeak_stdinservice/config.pb.go

Lines changed: 89 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fleetspeak/src/client/stdinservice/proto/fleetspeak_stdinservice/config.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,16 @@ message Config {
1212
// Command line arguments.
1313
// These arguments are prepended to the arguments specified in the message.
1414
repeated string args = 2;
15+
16+
// Log level for the service.
17+
LogLevel log_level = 3;
18+
}
19+
20+
// The log level for the service, defining what command output should be logged
21+
// locally. This does not affect the output that is included in responses to
22+
// the server.
23+
enum LogLevel {
24+
LOG_LEVEL_NONE = 0;
25+
LOG_LEVEL_STDERR = 1;
26+
LOG_LEVEL_ALL = 2;
1527
}

fleetspeak/src/client/stdinservice/stdinservice.go

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,19 @@ import (
2222
"fmt"
2323
"os/exec"
2424

25-
anypb "google.golang.org/protobuf/types/known/anypb"
26-
tspb "google.golang.org/protobuf/types/known/timestamppb"
27-
25+
log "github.com/golang/glog"
2826
"github.com/google/fleetspeak/fleetspeak/src/client/service"
2927

3028
sspb "github.com/google/fleetspeak/fleetspeak/src/client/stdinservice/proto/fleetspeak_stdinservice"
3129
fspb "github.com/google/fleetspeak/fleetspeak/src/common/proto/fleetspeak"
30+
anypb "google.golang.org/protobuf/types/known/anypb"
31+
tspb "google.golang.org/protobuf/types/known/timestamppb"
3232
)
3333

34+
// logOutputFunc is called after a command terminated to log its output.
35+
// Can be overridden in tests.
36+
var logOutputFunc = logOutput
37+
3438
// Factory is a service.Factory for StdinServices.
3539
//
3640
// In response to every received sspb.InputMessage, a StdinService fires
@@ -45,7 +49,6 @@ func Factory(conf *fspb.ClientServiceConfig) (service.Service, error) {
4549
if err != nil {
4650
return nil, err
4751
}
48-
4952
return &StdinService{
5053
conf: conf,
5154
ssConf: ssConf,
@@ -64,7 +67,6 @@ type StdinService struct {
6467
// Start starts the StdinService.
6568
func (s *StdinService) Start(sc service.Context) error {
6669
s.sc = sc
67-
6870
return nil
6971
}
7072

@@ -73,38 +75,47 @@ func (s *StdinService) ProcessMessage(ctx context.Context, m *fspb.Message) erro
7375
if m.MessageType != "StdinServiceInputMessage" {
7476
return fmt.Errorf("unrecognized common.Message.message_type: %q", m.MessageType)
7577
}
76-
7778
im := &sspb.InputMessage{}
7879
if err := m.Data.UnmarshalTo(im); err != nil {
7980
return fmt.Errorf("error while unmarshalling common.Message.data: %v", err)
8081
}
82+
om, err := s.execute(ctx, im)
83+
if err != nil {
84+
return fmt.Errorf("command failed: %v", err)
85+
}
86+
if err := s.respond(ctx, om); err != nil {
87+
return fmt.Errorf("error while trying to send a response to the requesting server: %v", err)
88+
}
89+
return nil
90+
}
8191

92+
func (s *StdinService) execute(ctx context.Context, im *sspb.InputMessage) (*sspb.OutputMessage, error) {
8293
var stdout, stderr bytes.Buffer
8394

84-
var args []string
85-
args = append(args, s.ssConf.Args...)
86-
args = append(args, im.Args...)
87-
95+
args := append(s.ssConf.Args, im.Args...)
8896
cmd := exec.CommandContext(ctx, s.ssConf.Cmd, args...)
8997
cmd.Stdin = bytes.NewBuffer(im.Input)
9098
cmd.Stdout = &stdout
9199
cmd.Stderr = &stderr
92100

93101
err := cmd.Run()
102+
103+
if s.ssConf.LogLevel >= sspb.LogLevel_LOG_LEVEL_STDERR {
104+
logOutputFunc(s.conf.Name, "stderr", &stderr)
105+
}
106+
if s.ssConf.LogLevel == sspb.LogLevel_LOG_LEVEL_ALL {
107+
logOutputFunc(s.conf.Name, "stdout", &stdout)
108+
}
109+
94110
if err != nil {
95-
return err
111+
return nil, err
96112
}
97113

98-
om := &sspb.OutputMessage{
114+
return &sspb.OutputMessage{
99115
Stdout: stdout.Bytes(),
100116
Stderr: stderr.Bytes(),
101117
Timestamp: tspb.Now(),
102-
}
103-
if err := s.respond(ctx, om); err != nil {
104-
return fmt.Errorf("error while trying to send a response to the requesting server: %v", err)
105-
}
106-
107-
return nil
118+
}, nil
108119
}
109120

110121
// Stop stops the StdinService.
@@ -118,14 +129,23 @@ func (s *StdinService) respond(ctx context.Context, om *sspb.OutputMessage) erro
118129
if err != nil {
119130
return err
120131
}
121-
122132
m := &fspb.Message{
123133
Destination: &fspb.Address{
124134
ServiceName: s.conf.Name,
125135
},
126136
MessageType: "StdinServiceOutputMessage",
127137
Data: data,
128138
}
129-
130139
return s.sc.Send(ctx, service.AckMessage{M: m})
131140
}
141+
142+
func logOutput(name, level string, buf *bytes.Buffer) {
143+
str := buf.String()
144+
if str == "" {
145+
return
146+
}
147+
if len(str) > 4096 {
148+
str = str[:4096] + "\n[truncated]"
149+
}
150+
log.Infof("StdinService %q command %s:\n%s", name, level, str)
151+
}

0 commit comments

Comments
 (0)