Skip to content

Commit

Permalink
Add Sidecar log level through GS specification (#1007)
Browse files Browse the repository at this point in the history
Add ability to specify logrus log level in yaml configuration and
apply this log level on creating the GameServer.
  • Loading branch information
aLekSer authored and roberthbailey committed Sep 20, 2019
1 parent fa69d11 commit fc9169c
Show file tree
Hide file tree
Showing 10 changed files with 1,024 additions and 1,001 deletions.
3 changes: 3 additions & 0 deletions examples/fleet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ spec:
health:
initialDelaySeconds: 30
periodSeconds: 60
# logging parameters for game server sidecar
logging:
sdkServer: Info
# The GameServer's Pod template
template:
spec:
Expand Down
9 changes: 8 additions & 1 deletion examples/gameserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ spec:
ports:
# name is a descriptive name for the port
- name: default
# portPolicy has two options:
# portPolicy has three options:
# - "Dynamic" (default) the system allocates a free hostPort for the gameserver, for game clients to connect to
# - "Static", user defines the hostPort that the game client will connect to. Then onus is on the user to ensure that the
# - "Passthrough" dynamically sets the `containerPort` to the same value as the dynamically selected hostPort.
Expand All @@ -60,6 +60,13 @@ spec:
# Minimum consecutive failures for the health probe to be considered failed after having succeeded.
# Defaults to 3. Minimum value is 1
failureThreshold: 3
# logging parameters for game server sidecar
logging:
# sdkServer logging parameter has three options:
# - "Info" (default) The SDK server will output all messages except for debug messages
# - "Debug" The SDK server will output all messages including debug messages
# - "Error" The SDK server will only output error messages
sdkServer: Info
# Pod template configuration
# https://v1-12.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.12/#podtemplate-v1-core
template:
Expand Down
15 changes: 15 additions & 0 deletions install/helm/agones/templates/crds/_gameserverspecvalidation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,21 @@ properties:
type: integer
minimum: 1
maximum: 65535
logging:
type: object
title: Define logging levels for agones system components
properties:
sdkServer:
type: string
description: |
sdkServer logging parameter has three options:
- "Info" (default) The SDK server will output all messages except for debug messages
- "Debug" The SDK server will output all messages including debug messages
- "Error" The SDK server will only output error messages
enum:
- Error
- Info
- Debug
scheduling:
type: string
enum:
Expand Down
45 changes: 45 additions & 0 deletions install/yaml/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,21 @@ spec:
type: integer
minimum: 1
maximum: 65535
logging:
type: object
title: Define logging levels for agones system components
properties:
sdkServer:
type: string
description: |
sdkServer logging parameter has three options:
- "Info" (default) The SDK server will output all messages except for debug messages
- "Debug" The SDK server will output all messages including debug messages
- "Error" The SDK server will only output error messages
enum:
- Error
- Info
- Debug
scheduling:
type: string
enum:
Expand Down Expand Up @@ -594,6 +609,21 @@ spec:
type: integer
minimum: 1
maximum: 65535
logging:
type: object
title: Define logging levels for agones system components
properties:
sdkServer:
type: string
description: |
sdkServer logging parameter has three options:
- "Info" (default) The SDK server will output all messages except for debug messages
- "Debug" The SDK server will output all messages including debug messages
- "Error" The SDK server will only output error messages
enum:
- Error
- Info
- Debug
scheduling:
type: string
enum:
Expand Down Expand Up @@ -860,6 +890,21 @@ spec:
type: integer
minimum: 1
maximum: 65535
logging:
type: object
title: Define logging levels for agones system components
properties:
sdkServer:
type: string
description: |
sdkServer logging parameter has three options:
- "Info" (default) The SDK server will output all messages except for debug messages
- "Debug" The SDK server will output all messages including debug messages
- "Error" The SDK server will only output error messages
enum:
- Error
- Info
- Debug
scheduling:
type: string
enum:
Expand Down
20 changes: 18 additions & 2 deletions pkg/apis/agones/v1/gameserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,20 @@ type GameServerSpec struct {
Ports []GameServerPort `json:"ports"`
// Health configures health checking
Health Health `json:"health,omitempty"`
// Scheduling strategy. Defaults to "Packed".
// Scheduling strategy. Defaults to "Packed"
Scheduling apis.SchedulingStrategy `json:"scheduling,omitempty"`
// Logging specifies log levels for Agones system containers
Logging Logging `json:"logging,omitempty"`
// Template describes the Pod that will be created for the GameServer
Template corev1.PodTemplateSpec `json:"template"`
}

// Logging specifies log levels for Agones system containers
type Logging struct {
// SdkServer is a log level for SDK server (sidecar) logs. Defaults to "Info"
SdkServer string `json:"sdkServer,omitempty"`
}

// GameServerState is the state for the GameServer
type GameServerState string

Expand Down Expand Up @@ -213,9 +221,17 @@ func (gss *GameServerSpec) ApplyDefaults() {
gss.applyPortDefaults()
gss.applyHealthDefaults()
gss.applySchedulingDefaults()
gss.applyLogLevelDefaults()
}

// applyLogLevelDefaults applies the log level default - "Info"
func (gss *GameServerSpec) applyLogLevelDefaults() {
if gss.Logging.SdkServer == "" {
gss.Logging.SdkServer = "Info"
}
}

// applyContainerDefaults applues the container defaults
// applyContainerDefaults applies the container defaults
func (gss *GameServerSpec) applyContainerDefaults() {
if len(gss.Template.Spec.Containers) == 1 {
gss.Container = gss.Template.Spec.Containers[0].Name
Expand Down
53 changes: 44 additions & 9 deletions pkg/apis/agones/v1/gameserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ func TestGameServerApplyDefaults(t *testing.T) {
t.Parallel()

type expected struct {
protocol corev1.Protocol
state GameServerState
policy PortPolicy
health Health
scheduling apis.SchedulingStrategy
protocol corev1.Protocol
state GameServerState
policy PortPolicy
health Health
scheduling apis.SchedulingStrategy
sdkServerLogLevel string
}
data := map[string]struct {
gameServer GameServer
Expand Down Expand Up @@ -93,6 +94,7 @@ func TestGameServerApplyDefaults(t *testing.T) {
InitialDelaySeconds: 5,
PeriodSeconds: 5,
},
sdkServerLogLevel: "Info",
},
},
"defaults on passthrough": {
Expand All @@ -116,6 +118,7 @@ func TestGameServerApplyDefaults(t *testing.T) {
InitialDelaySeconds: 5,
PeriodSeconds: 5,
},
sdkServerLogLevel: "Info",
},
},
"defaults are already set": {
Expand All @@ -138,6 +141,7 @@ func TestGameServerApplyDefaults(t *testing.T) {
{Name: "testing", Image: "testing/image"},
{Name: "testing2", Image: "testing/image2"}}},
},
Logging: Logging{SdkServer: "Info"},
},
Status: GameServerStatus{State: "TestState"}},
container: "testing2",
Expand All @@ -152,6 +156,7 @@ func TestGameServerApplyDefaults(t *testing.T) {
InitialDelaySeconds: 11,
PeriodSeconds: 12,
},
sdkServerLogLevel: "Info",
},
},
"set basic defaults on static gameserver": {
Expand All @@ -173,6 +178,7 @@ func TestGameServerApplyDefaults(t *testing.T) {
InitialDelaySeconds: 5,
PeriodSeconds: 5,
},
sdkServerLogLevel: "Info",
},
},
"health is disabled": {
Expand All @@ -192,6 +198,7 @@ func TestGameServerApplyDefaults(t *testing.T) {
health: Health{
Disabled: true,
},
sdkServerLogLevel: "Info",
},
},
"convert from legacy single port to multiple": {
Expand All @@ -211,11 +218,37 @@ func TestGameServerApplyDefaults(t *testing.T) {
},
container: "testing",
expected: expected{
protocol: corev1.ProtocolTCP,
state: GameServerStateCreating,
policy: Static,
protocol: corev1.ProtocolTCP,
state: GameServerStateCreating,
policy: Static,
scheduling: apis.Packed,
health: Health{Disabled: true},
sdkServerLogLevel: "Info",
},
},
"set Debug logging level": {
gameServer: GameServer{
Spec: GameServerSpec{
Ports: []GameServerPort{{ContainerPort: 999}},
Logging: Logging{SdkServer: "Debug"},
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{Containers: []corev1.Container{
{Name: "testing", Image: "testing/image"},
}}}},
},
container: "testing",
expected: expected{
protocol: "UDP",
state: GameServerStatePortAllocation,
policy: Dynamic,
scheduling: apis.Packed,
health: Health{Disabled: true},
health: Health{
Disabled: false,
FailureThreshold: 3,
InitialDelaySeconds: 5,
PeriodSeconds: 5,
},
sdkServerLogLevel: "Debug",
},
},
}
Expand All @@ -233,6 +266,7 @@ func TestGameServerApplyDefaults(t *testing.T) {
assert.Equal(t, test.expected.state, test.gameServer.Status.State)
assert.Equal(t, test.expected.health, test.gameServer.Spec.Health)
assert.Equal(t, test.expected.scheduling, test.gameServer.Spec.Scheduling)
assert.Equal(t, test.expected.sdkServerLogLevel, test.gameServer.Spec.Logging.SdkServer)
})
}
}
Expand Down Expand Up @@ -481,6 +515,7 @@ func TestGameServerPatch(t *testing.T) {

assert.Contains(t, string(patch), `{"op":"replace","path":"/spec/container","value":"bear"}`)
}

func TestGameServerGetDevAddress(t *testing.T) {
devGs := &GameServer{
ObjectMeta: metav1.ObjectMeta{
Expand Down
23 changes: 18 additions & 5 deletions pkg/sdkserver/sdkserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func NewSDKServer(gameServerName, namespace string, kubeClient kubernetes.Interf
logfields.GameServerKey,
strings.Join([]string{agones.GroupName, s.namespace, s.gameServerName}, "."))

s.logger.Info("created GameServer sidecar")
s.logger.Info("Created GameServer sidecar")

return s, nil
}
Expand All @@ -191,9 +191,22 @@ func (s *SDKServer) Run(stop <-chan struct{}) error {
return err
}

logLevel := "info"
// grab configuration details
if gs.Spec.Logging.SdkServer != "" {
logLevel = strings.ToLower(gs.Spec.Logging.SdkServer)
}
s.logger.WithField("logLevel", logLevel).Info("Setting LogLevel configuration")
level, err := logrus.ParseLevel(logLevel)
if err == nil {
s.logger.Logger.SetLevel(level)
} else {
s.logger.WithError(err).Info("Specified wrong Logging.SdkServer. Setting default loglevel - Info")
s.logger.Logger.SetLevel(logrus.InfoLevel)
}

s.health = gs.Spec.Health
s.logger.WithField("health", s.health).Info("setting health configuration")
s.logger.WithField("health", s.health).Info("Setting health configuration")
s.healthTimeout = time.Duration(gs.Spec.Health.PeriodSeconds) * time.Second
s.initHealthLastUpdated(time.Duration(gs.Spec.Health.InitialDelaySeconds) * time.Second)

Expand All @@ -214,7 +227,7 @@ func (s *SDKServer) Run(stop <-chan struct{}) error {
go func() {
if err := s.server.ListenAndServe(); err != nil {
if err == http.ErrServerClosed {
s.logger.WithError(err).Info("health check: http server closed")
s.logger.WithError(err).Info("Health check: http server closed")
} else {
err = errors.Wrap(err, "Could not listen on :8080")
runtime.HandleError(s.logger.WithError(err), err)
Expand Down Expand Up @@ -319,7 +332,7 @@ func (s *SDKServer) gameServer() (*agonesv1.GameServer, error) {
// updateLabels updates the labels on this GameServer to the ones persisted in SDKServer,
// i.e. SDKServer.gsLabels, with the prefix of "agones.dev/sdk-"
func (s *SDKServer) updateLabels() error {
s.logger.WithField("labels", s.gsLabels).Info("updating label")
s.logger.WithField("labels", s.gsLabels).Info("Updating label")
gs, err := s.gameServer()
if err != nil {
return err
Expand Down Expand Up @@ -534,7 +547,7 @@ func (s *SDKServer) sendGameServerUpdate(gs *agonesv1.GameServer) {
func (s *SDKServer) runHealth() {
s.checkHealth()
if !s.healthy() {
s.logger.WithField("gameServerName", s.gameServerName).Info("has failed health check")
s.logger.WithField("gameServerName", s.gameServerName).Info("GameServer has failed health check")
s.enqueueState(agonesv1.GameServerStateUnhealthy)
}
}
Expand Down
Loading

0 comments on commit fc9169c

Please sign in to comment.