Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable config switch #191

Merged
merged 11 commits into from
Sep 22, 2023
42 changes: 34 additions & 8 deletions cmd/splunk-extension-wrapper/splunk-extension-wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,32 @@ import (
// the correct value is set by the go linker (it's done during build using "ldflags")
var gitVersion string

const enabledKey = "SPLUNK_EXTENSION_WRAPPER_ENABLED"
const extensionNameKey = "SPLUNK_EXTENSION_WRAPPER_NAME"

func enabled() bool {
s := strings.ToLower(os.Getenv(enabledKey))
return s != "0" && s != "false"
}

func main() {
enabled := enabled()

configuration := config.New()

initLogging(&configuration)

ossignal.Watch()

m := metrics.New()
// When we are running "disabled", don't actually try to emit metrics.
// A cleaner design for this would use an interface with a stub implementation,
// but 3 or 4 nil checks will do for now, since they're all in one file
var m *metrics.MetricEmitter = nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of a nit, especially if this library is going away, but might be nice to instead extract an interface and use a no-op implementation so we don't have to check for nil before calling methods on the variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I like that. I'll add a comment to this effect for now.

if enabled {
m = metrics.New()
}

shutdownCondition := registerApiAndStartMainLoop(m, &configuration)
shutdownCondition := registerApiAndStartMainLoop(enabled, m, &configuration)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a nit and just a personal style preference (it's also in Clean Code!): instead of passing in a boolean flag then modifying the behavior of the function based on its value, consider creating two separate functions.


if shutdownCondition.IsError() {
log.SetOutput(os.Stderr)
Expand All @@ -51,10 +67,12 @@ func main() {
log.Println("shutdown reason:", shutdownCondition.Reason())
log.Println("shutdown message:", shutdownCondition.Message())

m.Shutdown(shutdownCondition)
if m != nil {
m.Shutdown(shutdownCondition)
}
}

func registerApiAndStartMainLoop(m *metrics.MetricEmitter, configuration *config.Configuration) (sc shutdown.Condition) {
func registerApiAndStartMainLoop(enabled bool, m *metrics.MetricEmitter, configuration *config.Configuration) (sc shutdown.Condition) {
var api *extensionapi.RegisteredApi

defer func() {
Expand All @@ -67,7 +85,7 @@ func registerApiAndStartMainLoop(m *metrics.MetricEmitter, configuration *config
}
}()

api, sc = extensionapi.Register(extensionName(), configuration)
api, sc = extensionapi.Register(enabled, extensionName(), configuration)

if sc == nil {
sc = mainLoop(api, m, configuration)
Expand All @@ -81,13 +99,17 @@ func registerApiAndStartMainLoop(m *metrics.MetricEmitter, configuration *config
}

func mainLoop(api *extensionapi.RegisteredApi, m *metrics.MetricEmitter, configuration *config.Configuration) (sc shutdown.Condition) {
m.SetFunction(api.FunctionName, api.FunctionVersion)
if m != nil {
m.SetFunction(api.FunctionName, api.FunctionVersion)
}

var event *extensionapi.Event
event, sc = api.NextEvent()

for sc == nil {
sc = m.Invoked(event.InvokedFunctionArn, configuration.SplunkFailFast)
if m != nil {
sc = m.Invoked(event.InvokedFunctionArn, configuration.SplunkFailFast)
}
if sc == nil {
event, sc = api.NextEvent()
}
Expand Down Expand Up @@ -121,5 +143,9 @@ func initLogging(configuration *config.Configuration) {
}

func extensionName() string {
return path.Base(os.Args[0])
name := os.Getenv(extensionNameKey)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: another way to write this function using Go idioms:

	if name := os.Getenv(extensionNameKey); name != "" {
		return name
	}
	return path.Base(os.Args[0])

if name == "" {
name = path.Base(os.Args[0])
}
return name
}
12 changes: 9 additions & 3 deletions internal/extensionapi/extensionapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,17 @@ type RegisteredApi struct {
registerResponse
}

func Register(name string, configuration *config.Configuration) (*RegisteredApi, shutdown.Condition) {
log.Println("Registering...")
func Register(enabled bool, name string, configuration *config.Configuration) (*RegisteredApi, shutdown.Condition) {
log.Println("Registering... " + name)
// extensions have to at least call Register and Next; they can't actually be "disabled"
// so if we are not enabled, at least subscribe to SHUTDOWN
events := []string{ shutdownType }
if enabled {
events = []string{ invokeType, shutdownType }
}

rb, err := json.Marshal(map[string][]string{
"events": {invokeType, shutdownType}})
"events": events})

if err != nil {
return nil, shutdown.Api(fmt.Sprintf("can't marshall body: %v", err))
Expand Down