K8s: standalone: use Grafana's logger to stream all logs (#84530)
--- Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
co-authored by
Marcus Efraimsson
parent
3ea5c08c88
commit
2d1cd82a98
@@ -12,14 +12,19 @@ aggregation path altogether and just run this example apiserver as a standalone
|
|||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
go run ./pkg/cmd/grafana apiserver example.grafana.app \
|
go run ./pkg/cmd/grafana apiserver \
|
||||||
|
--runtime-config=example.grafana.app/v0alpha1=true \
|
||||||
|
--grafana-apiserver-dev-mode \
|
||||||
|
--verbosity 10 \
|
||||||
--secure-port 7443
|
--secure-port 7443
|
||||||
```
|
```
|
||||||
|
|
||||||
### Verify that all works
|
### Verify that all works
|
||||||
|
|
||||||
|
In dev mode, the standalone server's loopback kubeconfig is written to `./data/grafana-apiserver/apiserver.kubeconfig`.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
export KUBECONFIG=./example-apiserver/kubeconfig
|
export KUBECONFIG=./data/grafana-apiserver/apiserver.kubeconfig
|
||||||
|
|
||||||
kubectl api-resources
|
kubectl api-resources
|
||||||
NAME SHORTNAMES APIVERSION NAMESPACED KIND
|
NAME SHORTNAMES APIVERSION NAMESPACED KIND
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
"k8s.io/apiserver/pkg/server/options"
|
|
||||||
"k8s.io/component-base/cli"
|
"k8s.io/component-base/cli"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/server"
|
"github.com/grafana/grafana/pkg/server"
|
||||||
grafanaapiserver "github.com/grafana/grafana/pkg/services/apiserver"
|
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/standalone"
|
"github.com/grafana/grafana/pkg/services/apiserver/standalone"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,6 +29,14 @@ func newCommandStartExampleAPIServer(o *APIServerOptions, stopCh <-chan struct{}
|
|||||||
devAcknowledgementNotice,
|
devAcknowledgementNotice,
|
||||||
Example: "grafana apiserver --runtime-config=example.grafana.app/v0alpha1=true",
|
Example: "grafana apiserver --runtime-config=example.grafana.app/v0alpha1=true",
|
||||||
RunE: func(c *cobra.Command, args []string) error {
|
RunE: func(c *cobra.Command, args []string) error {
|
||||||
|
if err := log.SetupConsoleLogger("debug"); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
runtime, err := standalone.ReadRuntimeConfig(runtimeConfig)
|
runtime, err := standalone.ReadRuntimeConfig(runtimeConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -67,11 +74,9 @@ func newCommandStartExampleAPIServer(o *APIServerOptions, stopCh <-chan struct{}
|
|||||||
factoryOptions.AddFlags(cmd.Flags())
|
factoryOptions.AddFlags(cmd.Flags())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o.ExtraOptions.AddFlags(cmd.Flags())
|
||||||
|
|
||||||
// Register standard k8s flags with the command line
|
// Register standard k8s flags with the command line
|
||||||
o.RecommendedOptions = options.NewRecommendedOptions(
|
|
||||||
defaultEtcdPathPrefix,
|
|
||||||
grafanaapiserver.Codecs.LegacyCodec(), // the codec is passed to etcd and not used
|
|
||||||
)
|
|
||||||
o.RecommendedOptions.AddFlags(cmd.Flags())
|
o.RecommendedOptions.AddFlags(cmd.Flags())
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apiserver/builder"
|
"github.com/grafana/grafana/pkg/apiserver/builder"
|
||||||
grafanaAPIServer "github.com/grafana/grafana/pkg/services/apiserver"
|
grafanaAPIServer "github.com/grafana/grafana/pkg/services/apiserver"
|
||||||
|
grafanaAPIServerOptions "github.com/grafana/grafana/pkg/services/apiserver/options"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/standalone"
|
"github.com/grafana/grafana/pkg/services/apiserver/standalone"
|
||||||
"github.com/grafana/grafana/pkg/services/apiserver/utils"
|
"github.com/grafana/grafana/pkg/services/apiserver/utils"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@@ -29,6 +30,7 @@ const (
|
|||||||
type APIServerOptions struct {
|
type APIServerOptions struct {
|
||||||
factory standalone.APIServerFactory
|
factory standalone.APIServerFactory
|
||||||
builders []builder.APIGroupBuilder
|
builders []builder.APIGroupBuilder
|
||||||
|
ExtraOptions *grafanaAPIServerOptions.ExtraOptions
|
||||||
RecommendedOptions *options.RecommendedOptions
|
RecommendedOptions *options.RecommendedOptions
|
||||||
AlternateDNS []string
|
AlternateDNS []string
|
||||||
|
|
||||||
@@ -40,6 +42,11 @@ func newAPIServerOptions(out, errOut io.Writer) *APIServerOptions {
|
|||||||
return &APIServerOptions{
|
return &APIServerOptions{
|
||||||
StdOut: out,
|
StdOut: out,
|
||||||
StdErr: errOut,
|
StdErr: errOut,
|
||||||
|
RecommendedOptions: options.NewRecommendedOptions(
|
||||||
|
defaultEtcdPathPrefix,
|
||||||
|
grafanaAPIServer.Codecs.LegacyCodec(), // the codec is passed to etcd and not used
|
||||||
|
),
|
||||||
|
ExtraOptions: grafanaAPIServerOptions.NewExtraOptions(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +155,12 @@ func (o *APIServerOptions) Config() (*genericapiserver.RecommendedConfig, error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.ExtraOptions != nil {
|
||||||
|
if err := o.ExtraOptions.ApplyTo(serverConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
serverConfig.DisabledPostStartHooks = serverConfig.DisabledPostStartHooks.Insert("generic-apiserver-start-informers")
|
serverConfig.DisabledPostStartHooks = serverConfig.DisabledPostStartHooks.Insert("generic-apiserver-start-informers")
|
||||||
serverConfig.DisabledPostStartHooks = serverConfig.DisabledPostStartHooks.Insert("priority-and-fairness-config-consumer")
|
serverConfig.DisabledPostStartHooks = serverConfig.DisabledPostStartHooks.Insert("priority-and-fairness-config-consumer")
|
||||||
|
|
||||||
@@ -165,12 +178,15 @@ func (o *APIServerOptions) Config() (*genericapiserver.RecommendedConfig, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates APIServerOptions
|
// Validate validates APIServerOptions
|
||||||
// NOTE: we don't call validate on the top level recommended options as it doesn't like skipping etcd-servers
|
func (o *APIServerOptions) Validate() error {
|
||||||
// the function is left here for troubleshooting any other config issues
|
errors := make([]error, 0)
|
||||||
func (o *APIServerOptions) Validate(args []string) error {
|
// NOTE: we don't call validate on the top level recommended options as it doesn't like skipping etcd-servers
|
||||||
errors := []error{}
|
// the function is left here for troubleshooting any other config issues
|
||||||
errors = append(errors, o.RecommendedOptions.Validate()...)
|
// errors = append(errors, o.RecommendedOptions.Validate()...)
|
||||||
errors = append(errors, o.factory.GetOptions().ValidateOptions()...)
|
if factoryOptions := o.factory.GetOptions(); factoryOptions != nil {
|
||||||
|
errors = append(errors, factoryOptions.ValidateOptions()...)
|
||||||
|
}
|
||||||
|
|
||||||
return utilerrors.NewAggregate(errors)
|
return utilerrors.NewAggregate(errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +199,7 @@ func (o *APIServerOptions) RunAPIServer(config *genericapiserver.RecommendedConf
|
|||||||
delegationTarget := genericapiserver.NewEmptyDelegate()
|
delegationTarget := genericapiserver.NewEmptyDelegate()
|
||||||
completedConfig := config.Complete()
|
completedConfig := config.Complete()
|
||||||
|
|
||||||
server, err := completedConfig.New("example-apiserver", delegationTarget)
|
server, err := completedConfig.New("standalone-apiserver", delegationTarget)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -195,11 +211,13 @@ func (o *APIServerOptions) RunAPIServer(config *genericapiserver.RecommendedConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write the local config to disk
|
// write the local config to disk
|
||||||
if err = clientcmd.WriteToFile(
|
if o.ExtraOptions.DevMode {
|
||||||
utils.FormatKubeConfig(server.LoopbackClientConfig),
|
if err = clientcmd.WriteToFile(
|
||||||
path.Join(dataPath, "apiserver.kubeconfig"),
|
utils.FormatKubeConfig(server.LoopbackClientConfig),
|
||||||
); err != nil {
|
path.Join(dataPath, "apiserver.kubeconfig"),
|
||||||
return err
|
); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return server.PrepareRun().Run(stopCh)
|
return server.PrepareRun().Run(stopCh)
|
||||||
|
|||||||
@@ -499,3 +499,34 @@ func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupConsoleLogger setup Grafana console logger with provided level.
|
||||||
|
func SetupConsoleLogger(level string) error {
|
||||||
|
iniFile := ini.Empty()
|
||||||
|
sLog, err := iniFile.NewSection("log")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = sLog.NewKey("level", level)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sLogConsole, err := iniFile.NewSection("log.console")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = sLogConsole.NewKey("format", "console")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ReadLoggingConfig([]string{"console"}, "", iniFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user