| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package samba |
| 4 | |
| 5 | import ( |
| 6 | "fmt" |
| 7 | "strings" |
| 8 | |
| 9 | "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi" |
| 10 | ) |
| 11 | |
| 12 | const ( |
| 13 | prioSyscallCalls = collectorapi.Priority + iota |
| 14 | prioSyscallTransferredData |
| 15 | |
| 16 | prioSmb2CallCalls |
| 17 | prioSmb2CallTransferredData |
| 18 | ) |
| 19 | |
| 20 | var ( |
| 21 | syscallCallsChartTmpl = collectorapi.Chart{ |
| 22 | ID: "syscall_%s_calls", |
| 23 | Title: "Syscalls Count", |
| 24 | Units: "calls/s", |
| 25 | Fam: "syscalls", |
| 26 | Ctx: "samba.syscall_calls", |
| 27 | Priority: prioSyscallCalls, |
| 28 | Type: collectorapi.Line, |
| 29 | Dims: collectorapi.Dims{ |
| 30 | {ID: "syscall_%s_count", Name: "syscalls", Algo: collectorapi.Incremental}, |
| 31 | }, |
| 32 | } |
| 33 | syscallTransferredDataChartTmpl = collectorapi.Chart{ |
| 34 | ID: "syscall_%s_transferred_data", |
| 35 | Title: "Syscall Transferred Data", |
| 36 | Units: "bytes/s", |
| 37 | Fam: "syscalls", |
| 38 | Ctx: "samba.syscall_transferred_data", |
| 39 | Priority: prioSyscallTransferredData, |
| 40 | Type: collectorapi.Area, |
| 41 | Dims: collectorapi.Dims{ |
| 42 | {ID: "syscall_%s_bytes", Name: "transferred", Algo: collectorapi.Incremental}, |
| 43 | }, |
| 44 | } |
| 45 | |
| 46 | smb2CallCallsChartTmpl = collectorapi.Chart{ |
| 47 | ID: "smb2_call_%s_calls", |
| 48 | Title: "SMB2 Calls Count", |
| 49 | Units: "calls/s", |
| 50 | Fam: "smb2 calls", |
| 51 | Ctx: "samba.smb2_call_calls", |
| 52 | Priority: prioSmb2CallCalls, |
| 53 | Type: collectorapi.Line, |
| 54 | Dims: collectorapi.Dims{ |
| 55 | {ID: "smb2_%s_count", Name: "smb2", Algo: collectorapi.Incremental}, |
| 56 | }, |
| 57 | } |
| 58 | smb2CallTransferredDataChartTmpl = collectorapi.Chart{ |
| 59 | ID: "smb2_call_%s_transferred_data", |
| 60 | Title: "SMB2 Call Transferred Data", |
| 61 | Units: "bytes/s", |
| 62 | Fam: "smb2 calls", |
| 63 | Ctx: "samba.smb2_call_transferred_data", |
| 64 | Priority: prioSmb2CallTransferredData, |
| 65 | Type: collectorapi.Area, |
| 66 | Dims: collectorapi.Dims{ |
| 67 | {ID: "smb2_%s_inbytes", Name: "in", Algo: collectorapi.Incremental}, |
| 68 | {ID: "smb2_%s_outbytes", Name: "out", Algo: collectorapi.Incremental, Mul: -1}, |
| 69 | }, |
| 70 | } |
| 71 | ) |
| 72 | |
| 73 | func (c *Collector) addCharts(mx map[string]int64) { |
| 74 | for k := range mx { |
| 75 | if name, ok := extractCallName(k, "syscall_", "_count"); ok { |
| 76 | c.addSysCallChart(name, syscallCallsChartTmpl.Copy()) |
| 77 | } else if name, ok := extractCallName(k, "syscall_", "_bytes"); ok { |
| 78 | c.addSysCallChart(name, syscallTransferredDataChartTmpl.Copy()) |
| 79 | } else if name, ok := extractCallName(k, "smb2_", "_count"); ok { |
| 80 | c.addSmb2CallChart(name, smb2CallCallsChartTmpl.Copy()) |
| 81 | // all smb2* metrics have inbytes and outbytes |
| 82 | c.addSmb2CallChart(name, smb2CallTransferredDataChartTmpl.Copy()) |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | func (c *Collector) addSysCallChart(syscall string, chart *collectorapi.Chart) { |
| 88 | chart = chart.Copy() |
| 89 | chart.ID = fmt.Sprintf(chart.ID, syscall) |
| 90 | chart.Labels = []collectorapi.Label{ |
| 91 | {Key: "syscall", Value: syscall}, |
| 92 | } |
| 93 | for _, dim := range chart.Dims { |
| 94 | dim.ID = fmt.Sprintf(dim.ID, syscall) |
| 95 | } |
| 96 | |
| 97 | if err := c.Charts().Add(chart); err != nil { |
| 98 | c.Warning(err) |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | func (c *Collector) addSmb2CallChart(smb2Call string, chart *collectorapi.Chart) { |
| 103 | chart = chart.Copy() |
| 104 | chart.ID = fmt.Sprintf(chart.ID, smb2Call) |
| 105 | chart.Labels = []collectorapi.Label{ |
| 106 | {Key: "smb2call", Value: smb2Call}, |
| 107 | } |
| 108 | for _, dim := range chart.Dims { |
| 109 | dim.ID = fmt.Sprintf(dim.ID, smb2Call) |
| 110 | } |
| 111 | |
| 112 | if err := c.Charts().Add(chart); err != nil { |
| 113 | c.Warning(err) |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | func extractCallName(s, prefix, suffix string) (string, bool) { |
| 118 | if !strings.HasPrefix(s, prefix) || !strings.HasSuffix(s, suffix) { |
| 119 | return "", false |
| 120 | } |
| 121 | name := strings.TrimPrefix(s, prefix) |
| 122 | name = strings.TrimSuffix(name, suffix) |
| 123 | return name, true |
| 124 | } |