The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/supportbundles/supportbundlesimpl/collectors.go

191 lines
7.0 KiB

package supportbundlesimpl
import (
"context"
"encoding/json"
"fmt"
"runtime"
"time"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/supportbundles"
"github.com/grafana/grafana/pkg/setting"
)
func basicCollector(cfg *setting.Cfg) supportbundles.Collector {
return supportbundles.Collector{
UID: "basic",
DisplayName: "Basic information",
Description: "Basic information about the Grafana instance",
IncludedByDefault: true,
Default: true,
Fn: func(ctx context.Context) (*supportbundles.SupportItem, error) {
type basicInfo struct {
Version string `json:"version"` // Version is the version of Grafana instance.
Commit string `json:"commit"` // Commit is the commit hash of the Grafana instance.
CollectionDate time.Time `json:"collection_date"` // CollectionDate is the date when the support bundle was created.
DefaultTimezone string `json:"default_timezone"` // DefaultTimezone is the default timezone of the Grafana instance.
Alloc uint64 `json:"alloc"` // Alloc is bytes of allocated heap objects.
TotalAlloc uint64 `json:"total_alloc"` // TotalAlloc is cumulative bytes allocated for heap objects.
Sys uint64 `json:"sys"` // Sys is the total bytes of memory obtained from the OS.
Mallocs uint64 `json:"mallocs"` // Mallocs is the cumulative count of heap objects allocated.
Frees uint64 `json:"frees"` // Frees is the cumulative count of heap objects freed.
NumGC uint32 `json:"num_gc"` // NumGC is the number of completed GC cycles.
PauseTotalNs uint64 `json:"pause_total_ns"` // PauseTotalNs is the cumulative nanoseconds in GC
NumCPU int `json:"num_cpu"` // NumCPU is the number of logical CPUs usable by the current process.
NumGoRoutines int `json:"num_go_routines"` // NumGoRoutines is the number of goroutines that currently exist.
GoVersion string `json:"go_version"` // GoVersion is the version of Go used to build the binary.
GoOS string `json:"go_os"` // GoOS is the operating system target used to build the binary.
GoArch string `json:"go_arch"` // GoArch is the architecture target used to build the binary.
GoCompiler string `json:"go_compiler"` // GoCompiler is the compiler used to build the binary.
}
memstats := runtime.MemStats{}
runtime.ReadMemStats(&memstats)
collectionDate := time.Now()
tz, offset := collectionDate.Zone()
loc, _ := time.LoadLocation("UTC")
now := collectionDate.In(loc)
info := basicInfo{
Version: cfg.BuildVersion,
Commit: cfg.BuildCommit,
CollectionDate: now,
DefaultTimezone: fmt.Sprintf("%s (UTC%+d)", tz, offset/60/60),
Alloc: memstats.Alloc,
TotalAlloc: memstats.TotalAlloc,
Sys: memstats.Sys,
Mallocs: memstats.Mallocs,
Frees: memstats.Frees,
NumGC: memstats.NumGC,
PauseTotalNs: memstats.PauseTotalNs,
NumCPU: runtime.NumCPU(),
NumGoRoutines: runtime.NumGoroutine(),
GoVersion: runtime.Version(),
GoOS: runtime.GOOS,
GoArch: runtime.GOARCH,
GoCompiler: runtime.Compiler,
}
data, err := json.MarshalIndent(info, "", " ")
if err != nil {
return nil, err
}
return &supportbundles.SupportItem{
Filename: "basic.json",
FileBytes: data,
}, nil
},
}
}
func settingsCollector(settings setting.Provider) supportbundles.Collector {
return supportbundles.Collector{
UID: "settings",
DisplayName: "Settings",
Description: "Settings of the Grafana instance",
IncludedByDefault: false,
Default: true,
Fn: func(ctx context.Context) (*supportbundles.SupportItem, error) {
current := settings.Current()
data, err := json.MarshalIndent(current, "", " ")
if err != nil {
return nil, err
}
return &supportbundles.SupportItem{
Filename: "settings.json",
FileBytes: data,
}, nil
},
}
}
func pluginInfoCollector(pluginStore pluginstore.Store, pluginSettings pluginsettings.Service, logger log.Logger) supportbundles.Collector {
return supportbundles.Collector{
UID: "plugins",
DisplayName: "Plugin information",
Description: "Plugin information for the Grafana instance",
IncludedByDefault: false,
Default: true,
Fn: func(ctx context.Context) (*supportbundles.SupportItem, error) {
type PluginInfo struct {
id string
Name string
Description string
PluginType string `json:"type"`
Author plugins.InfoLink `json:"author,omitempty"`
SignatureStatus plugins.SignatureStatus
SignatureType plugins.SignatureType
SignatureOrg string
GrafanaVersionDependency string `json:"grafanaVersionDependency,omitempty"`
Settings []pluginsettings.InfoDTO `json:"settings,omitempty"`
}
// plugin definitions
plugins := pluginStore.Plugins(ctx)
// plugin settings
settings, err := pluginSettings.GetPluginSettings(ctx, &pluginsettings.GetArgs{})
if err != nil {
logger.Debug("Failed to fetch plugin settings:", "err", err)
}
settingMap := make(map[string][]*pluginsettings.InfoDTO)
for _, ps := range settings {
settingMap[ps.PluginID] = append(settingMap[ps.PluginID], ps)
}
var pluginInfoList []PluginInfo
for _, plugin := range plugins {
// skip builtin and core plugins
if plugin.BuiltIn || plugin.IsCorePlugin() {
continue
}
// skip plugins that are included in another plugin
if plugin.IncludedInAppID != "" {
continue
}
pInfo := PluginInfo{
id: plugin.ID,
Name: plugin.Name,
Description: plugin.Info.Description,
PluginType: string(plugin.Type),
Author: plugin.Info.Author,
SignatureStatus: plugin.Signature,
SignatureType: plugin.SignatureType,
SignatureOrg: plugin.SignatureOrg,
GrafanaVersionDependency: plugin.Dependencies.GrafanaVersion,
}
for _, ps := range settingMap[plugin.ID] {
pInfo.Settings = append(pInfo.Settings, pluginsettings.InfoDTO{
OrgID: ps.OrgID,
Enabled: ps.Enabled,
PluginVersion: ps.PluginVersion,
})
}
pluginInfoList = append(pluginInfoList, pInfo)
}
data, err := json.MarshalIndent(pluginInfoList, "", " ")
if err != nil {
return nil, err
}
return &supportbundles.SupportItem{
Filename: "plugins.json",
FileBytes: data,
}, nil
},
}
}