Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2149092

Browse files
committed
feat: add stackdriver and json log options to coder server
1 parent 627fbe5 commit 2149092

File tree

10 files changed

+263
-7
lines changed

10 files changed

+263
-7
lines changed

cli/deployment/config.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,26 @@ func newConfig() *codersdk.DeploymentConfig {
471471
Default: false,
472472
},
473473
},
474+
Logging: &codersdk.LoggingConfig{
475+
Human: &codersdk.DeploymentConfigField[string]{
476+
Name: "Human Log Location",
477+
Usage: "Output human-readable logs to a given file.",
478+
Flag: "human-log",
479+
Default: "/dev/stderr",
480+
},
481+
JSON: &codersdk.DeploymentConfigField[string]{
482+
Name: "JSON Log Location",
483+
Usage: "Output JSON logs to a given file.",
484+
Flag: "json-log",
485+
Default: "",
486+
},
487+
Stackdriver: &codersdk.DeploymentConfigField[string]{
488+
Name: "Stackdriver Log Location",
489+
Usage: "Output Stackdriver compatible logs to a given file.",
490+
Flag: "stackdriver-log",
491+
Default: "",
492+
},
493+
},
474494
}
475495
}
476496

cli/server.go

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ import (
4646

4747
"cdr.dev/slog"
4848
"cdr.dev/slog/sloggers/sloghuman"
49+
"cdr.dev/slog/sloggers/slogjson"
50+
"cdr.dev/slog/sloggers/slogstackdriver"
4951
"github.com/coder/coder/buildinfo"
5052
"github.com/coder/coder/cli/cliui"
5153
"github.com/coder/coder/cli/config"
@@ -122,13 +124,11 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
122124
}
123125

124126
printLogo(cmd)
125-
logger := slog.Make(sloghuman.Sink(cmd.ErrOrStderr()))
126-
if ok, _ := cmd.Flags().GetBool(varVerbose); ok {
127-
logger = logger.Leveled(slog.LevelDebug)
128-
}
129-
if cfg.Trace.CaptureLogs.Value {
130-
logger = logger.AppendSinks(tracing.SlogSink{})
127+
logger, logCloser, err := makeLogger(cmd, cfg)
128+
if err != nil {
129+
return xerrors.Errorf("make logger: %w", err)
131130
}
131+
defer logCloser()
132132

133133
// Register signals early on so that graceful shutdown can't
134134
// be interrupted by additional signals. Note that we avoid
@@ -1145,6 +1145,11 @@ func newProvisionerDaemon(
11451145

11461146
// nolint: revive
11471147
func printLogo(cmd *cobra.Command) {
1148+
// Only print the logo in TTYs.
1149+
if !isTTYOut(cmd) {
1150+
return
1151+
}
1152+
11481153
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s - Software development on your infrastucture\n", cliui.Styles.Bold.Render("Coder "+buildinfo.Version()))
11491154
}
11501155

@@ -1512,3 +1517,64 @@ func redirectHTTPToAccessURL(handler http.Handler, accessURL *url.URL) http.Hand
15121517
func isLocalhost(host string) bool {
15131518
return host == "localhost" || host == "127.0.0.1" || host == "::1"
15141519
}
1520+
1521+
func makeLogger(cmd *cobra.Command, cfg *codersdk.DeploymentConfig) (slog.Logger, func(), error) {
1522+
var (
1523+
sinks = []slog.Sink{}
1524+
closers = []func() error{}
1525+
)
1526+
1527+
if cfg.Logging.Human.Value != "" {
1528+
if cfg.Logging.Human.Value == "/dev/stderr" {
1529+
sinks = append(sinks, sloghuman.Sink(cmd.ErrOrStderr()))
1530+
} else {
1531+
fi, err := os.OpenFile(cfg.Logging.Human.Value, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
1532+
if err != nil {
1533+
return slog.Logger{}, nil, xerrors.Errorf("open human log %q: %w", cfg.Logging.Human.Value, err)
1534+
}
1535+
closers = append(closers, fi.Close)
1536+
sinks = append(sinks, sloghuman.Sink(fi))
1537+
}
1538+
}
1539+
1540+
if cfg.Logging.JSON.Value != "" {
1541+
if cfg.Logging.JSON.Value == "/dev/stderr" {
1542+
sinks = append(sinks, slogjson.Sink(cmd.ErrOrStderr()))
1543+
} else {
1544+
fi, err := os.OpenFile(cfg.Logging.JSON.Value, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
1545+
if err != nil {
1546+
return slog.Logger{}, nil, xerrors.Errorf("open json log %q: %w", cfg.Logging.JSON.Value, err)
1547+
}
1548+
closers = append(closers, fi.Close)
1549+
sinks = append(sinks, slogjson.Sink(fi))
1550+
}
1551+
}
1552+
1553+
if cfg.Logging.Stackdriver.Value != "" {
1554+
if cfg.Logging.JSON.Value == "/dev/stderr" {
1555+
sinks = append(sinks, slogstackdriver.Sink(cmd.ErrOrStderr()))
1556+
} else {
1557+
fi, err := os.OpenFile(cfg.Logging.Stackdriver.Value, os.O_WRONLY|os.O_WRONLY|os.O_APPEND, 0644)
1558+
if err != nil {
1559+
return slog.Logger{}, nil, xerrors.Errorf("open stackdriver log %q: %w", cfg.Logging.Stackdriver.Value, err)
1560+
}
1561+
closers = append(closers, fi.Close)
1562+
sinks = append(sinks, slogstackdriver.Sink(fi))
1563+
}
1564+
}
1565+
1566+
if cfg.Trace.CaptureLogs.Value {
1567+
sinks = append(sinks, tracing.SlogSink{})
1568+
}
1569+
1570+
level := slog.LevelInfo
1571+
if ok, _ := cmd.Flags().GetBool(varVerbose); ok {
1572+
level = slog.LevelDebug
1573+
}
1574+
1575+
return slog.Make(sinks...).Leveled(level), func() {
1576+
for _, closer := range closers {
1577+
_ = closer()
1578+
}
1579+
}, nil
1580+
}

coderd/apidoc/docs.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5362,6 +5362,9 @@ const docTemplate = `{
53625362
"in_memory_database": {
53635363
"$ref": "#/definitions/codersdk.DeploymentConfigField-bool"
53645364
},
5365+
"logging": {
5366+
"$ref": "#/definitions/codersdk.LoggingConfig"
5367+
},
53655368
"max_token_lifetime": {
53665369
"$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration"
53675370
},
@@ -5881,6 +5884,20 @@ const docTemplate = `{
58815884
"LogSourceProvisioner"
58825885
]
58835886
},
5887+
"codersdk.LoggingConfig": {
5888+
"type": "object",
5889+
"properties": {
5890+
"human": {
5891+
"$ref": "#/definitions/codersdk.DeploymentConfigField-string"
5892+
},
5893+
"json": {
5894+
"$ref": "#/definitions/codersdk.DeploymentConfigField-string"
5895+
},
5896+
"stackdriver": {
5897+
"$ref": "#/definitions/codersdk.DeploymentConfigField-string"
5898+
}
5899+
}
5900+
},
58845901
"codersdk.LoginType": {
58855902
"type": "string",
58865903
"enum": [

coderd/apidoc/swagger.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4757,6 +4757,9 @@
47574757
"in_memory_database": {
47584758
"$ref": "#/definitions/codersdk.DeploymentConfigField-bool"
47594759
},
4760+
"logging": {
4761+
"$ref": "#/definitions/codersdk.LoggingConfig"
4762+
},
47604763
"max_token_lifetime": {
47614764
"$ref": "#/definitions/codersdk.DeploymentConfigField-time_Duration"
47624765
},
@@ -5258,6 +5261,20 @@
52585261
"enum": ["provisioner_daemon", "provisioner"],
52595262
"x-enum-varnames": ["LogSourceProvisionerDaemon", "LogSourceProvisioner"]
52605263
},
5264+
"codersdk.LoggingConfig": {
5265+
"type": "object",
5266+
"properties": {
5267+
"human": {
5268+
"$ref": "#/definitions/codersdk.DeploymentConfigField-string"
5269+
},
5270+
"json": {
5271+
"$ref": "#/definitions/codersdk.DeploymentConfigField-string"
5272+
},
5273+
"stackdriver": {
5274+
"$ref": "#/definitions/codersdk.DeploymentConfigField-string"
5275+
}
5276+
}
5277+
},
52615278
"codersdk.LoginType": {
52625279
"type": "string",
52635280
"enum": ["password", "github", "oidc", "token"],

codersdk/deploymentconfig.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type DeploymentConfig struct {
4545
UpdateCheck *DeploymentConfigField[bool] `json:"update_check" typescript:",notnull"`
4646
MaxTokenLifetime *DeploymentConfigField[time.Duration] `json:"max_token_lifetime" typescript:",notnull"`
4747
Swagger *SwaggerConfig `json:"swagger" typescript:",notnull"`
48+
Logging *LoggingConfig `json:"logging" typescript:",notnull"`
4849
}
4950

5051
type DERP struct {
@@ -155,6 +156,12 @@ type SwaggerConfig struct {
155156
Enable *DeploymentConfigField[bool] `json:"enable" typescript:",notnull"`
156157
}
157158

159+
type LoggingConfig struct {
160+
Human *DeploymentConfigField[string] `json:"human" typescript:",notnull"`
161+
JSON *DeploymentConfigField[string] `json:"json" typescript:",notnull"`
162+
Stackdriver *DeploymentConfigField[string] `json:"stackdriver" typescript:",notnull"`
163+
}
164+
158165
type Flaggable interface {
159166
string | time.Duration | bool | int | []string | []GitAuthConfig
160167
}

docs/api/general.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,41 @@ curl -X GET http://coder-server:8080/api/v2/config/deployment \
335335
"usage": "string",
336336
"value": true
337337
},
338+
"logging": {
339+
"human": {
340+
"default": "string",
341+
"enterprise": true,
342+
"flag": "string",
343+
"hidden": true,
344+
"name": "string",
345+
"secret": true,
346+
"shorthand": "string",
347+
"usage": "string",
348+
"value": "string"
349+
},
350+
"json": {
351+
"default": "string",
352+
"enterprise": true,
353+
"flag": "string",
354+
"hidden": true,
355+
"name": "string",
356+
"secret": true,
357+
"shorthand": "string",
358+
"usage": "string",
359+
"value": "string"
360+
},
361+
"stackdriver": {
362+
"default": "string",
363+
"enterprise": true,
364+
"flag": "string",
365+
"hidden": true,
366+
"name": "string",
367+
"secret": true,
368+
"shorthand": "string",
369+
"usage": "string",
370+
"value": "string"
371+
}
372+
},
338373
"max_token_lifetime": {
339374
"default": 0,
340375
"enterprise": true,

docs/api/schemas.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,41 @@ CreateParameterRequest is a structure used to create a new parameter value for a
14081408
"usage": "string",
14091409
"value": true
14101410
},
1411+
"logging": {
1412+
"human": {
1413+
"default": "string",
1414+
"enterprise": true,
1415+
"flag": "string",
1416+
"hidden": true,
1417+
"name": "string",
1418+
"secret": true,
1419+
"shorthand": "string",
1420+
"usage": "string",
1421+
"value": "string"
1422+
},
1423+
"json": {
1424+
"default": "string",
1425+
"enterprise": true,
1426+
"flag": "string",
1427+
"hidden": true,
1428+
"name": "string",
1429+
"secret": true,
1430+
"shorthand": "string",
1431+
"usage": "string",
1432+
"value": "string"
1433+
},
1434+
"stackdriver": {
1435+
"default": "string",
1436+
"enterprise": true,
1437+
"flag": "string",
1438+
"hidden": true,
1439+
"name": "string",
1440+
"secret": true,
1441+
"shorthand": "string",
1442+
"usage": "string",
1443+
"value": "string"
1444+
}
1445+
},
14111446
"max_token_lifetime": {
14121447
"default": 0,
14131448
"enterprise": true,
@@ -2022,6 +2057,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a
20222057
| `gitauth` | [codersdk.DeploymentConfigField-array_codersdk_GitAuthConfig](#codersdkdeploymentconfigfield-array_codersdk_gitauthconfig) | false | | |
20232058
| `http_address` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | |
20242059
| `in_memory_database` | [codersdk.DeploymentConfigField-bool](#codersdkdeploymentconfigfield-bool) | false | | |
2060+
| `logging` | [codersdk.LoggingConfig](#codersdkloggingconfig) | false | | |
20252061
| `max_token_lifetime` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | |
20262062
| `metrics_cache_refresh_interval` | [codersdk.DeploymentConfigField-time_Duration](#codersdkdeploymentconfigfield-time_duration) | false | | |
20272063
| `oauth2` | [codersdk.OAuth2Config](#codersdkoauth2config) | false | | |
@@ -2558,6 +2594,54 @@ CreateParameterRequest is a structure used to create a new parameter value for a
25582594
| `provisioner_daemon` |
25592595
| `provisioner` |
25602596

2597+
## codersdk.LoggingConfig
2598+
2599+
```json
2600+
{
2601+
"human": {
2602+
"default": "string",
2603+
"enterprise": true,
2604+
"flag": "string",
2605+
"hidden": true,
2606+
"name": "string",
2607+
"secret": true,
2608+
"shorthand": "string",
2609+
"usage": "string",
2610+
"value": "string"
2611+
},
2612+
"json": {
2613+
"default": "string",
2614+
"enterprise": true,
2615+
"flag": "string",
2616+
"hidden": true,
2617+
"name": "string",
2618+
"secret": true,
2619+
"shorthand": "string",
2620+
"usage": "string",
2621+
"value": "string"
2622+
},
2623+
"stackdriver": {
2624+
"default": "string",
2625+
"enterprise": true,
2626+
"flag": "string",
2627+
"hidden": true,
2628+
"name": "string",
2629+
"secret": true,
2630+
"shorthand": "string",
2631+
"usage": "string",
2632+
"value": "string"
2633+
}
2634+
}
2635+
```
2636+
2637+
### Properties
2638+
2639+
| Name | Type | Required | Restrictions | Description |
2640+
| ------------- | ------------------------------------------------------------------------------ | -------- | ------------ | ----------- |
2641+
| `human` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | |
2642+
| `json` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | |
2643+
| `stackdriver` | [codersdk.DeploymentConfigField-string](#codersdkdeploymentconfigfield-string) | false | | |
2644+
25612645
## codersdk.LoginType
25622646

25632647
```json

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ require (
167167
tailscale.com v1.32.2
168168
)
169169

170+
require cloud.google.com/go/longrunning v0.1.1 // indirect
171+
170172
require (
171173
cloud.google.com/go/compute v1.12.1 // indirect
172174
filippo.io/edwards25519 v1.0.0-rc.1 // indirect

go.sum

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0c
3838
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
3939
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
4040
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
41-
cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=
4241
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
4342
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
4443
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -61,6 +60,7 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl
6160
cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU=
6261
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
6362
cloud.google.com/go/longrunning v0.1.1 h1:y50CXG4j0+qvEukslYFBCrzaXX0qpFbBzc3PchSu/LE=
63+
cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE=
6464
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
6565
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
6666
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=

0 commit comments

Comments
 (0)