summaryrefslogtreecommitdiffstats
path: root/src/go/plugin/go.d/modules/filecheck/charts.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/go/plugin/go.d/modules/filecheck/charts.go266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/go/plugin/go.d/modules/filecheck/charts.go b/src/go/plugin/go.d/modules/filecheck/charts.go
new file mode 100644
index 000000000..6d00463a6
--- /dev/null
+++ b/src/go/plugin/go.d/modules/filecheck/charts.go
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package filecheck
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module"
+)
+
+const (
+ prioFileExistenceStatus = module.Priority + iota
+ prioFileModificationTimeAgo
+ prioFileSize
+
+ prioDirExistenceStatus
+ prioDirModificationTimeAgo
+ prioDirSize
+ prioDirFilesCount
+)
+
+var (
+ fileExistenceStatusChartTmpl = module.Chart{
+ ID: "file_%s_existence_status",
+ Title: "File existence",
+ Units: "status",
+ Fam: "file existence",
+ Ctx: "filecheck.file_existence_status",
+ Priority: prioFileExistenceStatus,
+ Dims: module.Dims{
+ {ID: "file_%s_existence_status_exist", Name: "exist"},
+ {ID: "file_%s_existence_status_not_exist", Name: "not_exist"},
+ },
+ }
+
+ fileModificationTimeAgoChartTmpl = module.Chart{
+ ID: "file_%s_modification_time_ago",
+ Title: "File time since the last modification",
+ Units: "seconds",
+ Fam: "file mtime",
+ Ctx: "filecheck.file_modification_time_ago",
+ Priority: prioFileModificationTimeAgo,
+ Dims: module.Dims{
+ {ID: "file_%s_mtime_ago", Name: "mtime_ago"},
+ },
+ }
+ fileSizeChartTmpl = module.Chart{
+ ID: "file_%s_size",
+ Title: "File size",
+ Units: "bytes",
+ Fam: "file size",
+ Ctx: "filecheck.file_size_bytes",
+ Priority: prioFileSize,
+ Dims: module.Dims{
+ {ID: "file_%s_size_bytes", Name: "size"},
+ },
+ }
+)
+
+var (
+ dirExistenceStatusChartTmpl = module.Chart{
+ ID: "dir_%s_existence_status",
+ Title: "Directory existence",
+ Units: "status",
+ Fam: "dir existence",
+ Ctx: "filecheck.dir_existence_status",
+ Priority: prioDirExistenceStatus,
+ Dims: module.Dims{
+ {ID: "dir_%s_existence_status_exist", Name: "exist"},
+ {ID: "dir_%s_existence_status_not_exist", Name: "not_exist"},
+ },
+ }
+
+ dirModificationTimeAgoChartTmpl = module.Chart{
+ ID: "dir_%s_modification_time_ago",
+ Title: "Directory time since the last modification",
+ Units: "seconds",
+ Fam: "dir mtime",
+ Ctx: "filecheck.dir_modification_time_ago",
+ Priority: prioDirModificationTimeAgo,
+ Dims: module.Dims{
+ {ID: "dir_%s_mtime_ago", Name: "mtime_ago"},
+ },
+ }
+ dirSizeChartTmpl = module.Chart{
+ ID: "dir_%s_size",
+ Title: "Directory size",
+ Units: "bytes",
+ Fam: "dir size",
+ Ctx: "filecheck.dir_size_bytes",
+ Priority: prioDirSize,
+ Dims: module.Dims{
+ {ID: "dir_%s_size_bytes", Name: "size"},
+ },
+ }
+ dirFilesCountChartTmpl = module.Chart{
+ ID: "dir_%s_files_count",
+ Title: "Directory files count",
+ Units: "files",
+ Fam: "dir files",
+ Ctx: "filecheck.dir_files_count",
+ Priority: prioDirFilesCount,
+ Dims: module.Dims{
+ {ID: "dir_%s_files_count", Name: "files"},
+ },
+ }
+)
+
+func (f *Filecheck) updateFileCharts(infos []*statInfo) {
+ seen := make(map[string]bool)
+
+ for _, info := range infos {
+ seen[info.path] = true
+
+ sf := f.seenFiles.getp(info.path)
+
+ if !sf.hasExistenceCharts {
+ sf.hasExistenceCharts = true
+ f.addFileCharts(info.path,
+ fileExistenceStatusChartTmpl.Copy(),
+ )
+ }
+
+ if !sf.hasOtherCharts && info.fi != nil {
+ sf.hasOtherCharts = true
+ f.addFileCharts(info.path,
+ fileModificationTimeAgoChartTmpl.Copy(),
+ fileSizeChartTmpl.Copy(),
+ )
+
+ } else if sf.hasOtherCharts && info.fi == nil {
+ sf.hasOtherCharts = false
+ f.removeFileOtherCharts(info.path)
+ }
+ }
+
+ for path := range f.seenFiles.items {
+ if !seen[path] {
+ delete(f.seenFiles.items, path)
+ f.removeFileAllCharts(path)
+ }
+ }
+}
+
+func (f *Filecheck) updateDirCharts(infos []*statInfo) {
+ seen := make(map[string]bool)
+
+ for _, info := range infos {
+ seen[info.path] = true
+
+ sd := f.seenDirs.getp(info.path)
+
+ if !sd.hasExistenceCharts {
+ sd.hasExistenceCharts = true
+ f.addDirCharts(info.path,
+ dirExistenceStatusChartTmpl.Copy(),
+ )
+ }
+
+ if !sd.hasOtherCharts && info.fi != nil {
+ sd.hasOtherCharts = true
+ f.addDirCharts(info.path,
+ dirModificationTimeAgoChartTmpl.Copy(),
+ dirFilesCountChartTmpl.Copy(),
+ )
+ if f.Dirs.CollectDirSize {
+ f.addDirCharts(info.path,
+ dirSizeChartTmpl.Copy(),
+ )
+ }
+
+ } else if sd.hasOtherCharts && info.fi == nil {
+ sd.hasOtherCharts = false
+ f.removeDirOtherCharts(info.path)
+ }
+ }
+
+ for path := range f.seenDirs.items {
+ if !seen[path] {
+ delete(f.seenDirs.items, path)
+ f.removeDirAllCharts(path)
+ }
+ }
+}
+
+func (f *Filecheck) addFileCharts(filePath string, chartsTmpl ...*module.Chart) {
+ cs := append(module.Charts{}, chartsTmpl...)
+ charts := cs.Copy()
+
+ for _, chart := range *charts {
+ chart.ID = fmt.Sprintf(chart.ID, cleanPath(filePath))
+ chart.Labels = []module.Label{
+ {Key: "file_path", Value: filePath},
+ }
+ for _, dim := range chart.Dims {
+ dim.ID = fmt.Sprintf(dim.ID, filePath)
+ }
+ }
+
+ if err := f.Charts().Add(*charts...); err != nil {
+ f.Warning(err)
+ }
+}
+
+func (f *Filecheck) addDirCharts(dirPath string, chartsTmpl ...*module.Chart) {
+ cs := append(module.Charts{}, chartsTmpl...)
+ charts := cs.Copy()
+
+ for _, chart := range *charts {
+ chart.ID = fmt.Sprintf(chart.ID, cleanPath(dirPath))
+ chart.Labels = []module.Label{
+ {Key: "dir_path", Value: dirPath},
+ }
+ for _, dim := range chart.Dims {
+ dim.ID = fmt.Sprintf(dim.ID, dirPath)
+ }
+ }
+
+ if err := f.Charts().Add(*charts...); err != nil {
+ f.Warning(err)
+ }
+}
+
+func (f *Filecheck) removeFileAllCharts(filePath string) {
+ px := fmt.Sprintf("file_%s_", cleanPath(filePath))
+ f.removeCharts(func(id string) bool {
+ return strings.HasPrefix(id, px)
+ })
+}
+
+func (f *Filecheck) removeFileOtherCharts(filePath string) {
+ px := fmt.Sprintf("file_%s_", cleanPath(filePath))
+ f.removeCharts(func(id string) bool {
+ return strings.HasPrefix(id, px) && !strings.HasSuffix(id, "existence_status")
+ })
+}
+
+func (f *Filecheck) removeDirAllCharts(dirPath string) {
+ px := fmt.Sprintf("dir_%s_", cleanPath(dirPath))
+ f.removeCharts(func(id string) bool {
+ return strings.HasPrefix(id, px)
+ })
+}
+
+func (f *Filecheck) removeDirOtherCharts(dirPath string) {
+ px := fmt.Sprintf("dir_%s_", cleanPath(dirPath))
+ f.removeCharts(func(id string) bool {
+ return strings.HasPrefix(id, px) && !strings.HasSuffix(id, "existence_status")
+ })
+}
+
+func (f *Filecheck) removeCharts(match func(id string) bool) {
+ for _, chart := range *f.Charts() {
+ if match(chart.ID) {
+ chart.MarkRemove()
+ chart.MarkNotCreated()
+ }
+ }
+}
+
+func cleanPath(path string) string {
+ path = strings.ReplaceAll(path, " ", "_")
+ path = strings.ReplaceAll(path, ".", "_")
+ return path
+}