master
go 182 lines 4.73 KB
Raw
1 //go:build cgo
2
3 package as400
4
5 // SPDX-License-Identifier: GPL-3.0-or-later
6
7 import (
8 "context"
9 "fmt"
10 "time"
11
12 "github.com/netdata/netdata/go/plugins/pkg/confopt"
13 "github.com/netdata/netdata/go/plugins/pkg/matcher"
14 "github.com/netdata/netdata/go/plugins/plugin/ibm.d/framework"
15 "github.com/netdata/netdata/go/plugins/plugin/ibm.d/modules/as400/contexts"
16 as400proto "github.com/netdata/netdata/go/plugins/plugin/ibm.d/protocols/as400"
17 )
18
19 func defaultConfig() Config {
20 return Config{
21 Config: framework.Config{
22 UpdateEvery: 5,
23 },
24 Vnode: "",
25 DSN: "",
26 Timeout: confopt.Duration(2 * time.Second),
27
28 Hostname: "",
29 Port: 8471,
30 Username: "",
31 Password: "",
32 Database: "*SYSBAS",
33 ConnectionType: "odbc",
34 ODBCDriver: "IBM i Access ODBC Driver",
35 UseSSL: false,
36 ResetStatistics: false,
37
38 CollectDiskMetrics: confopt.AutoBoolAuto,
39 CollectSubsystemMetrics: confopt.AutoBoolAuto,
40 CollectActiveJobs: confopt.AutoBoolAuto,
41 CollectHTTPServerMetrics: confopt.AutoBoolAuto,
42 CollectPlanCacheMetrics: confopt.AutoBoolAuto,
43 CollectMessageQueueTotals: confopt.AutoBoolAuto,
44 CollectJobQueueTotals: confopt.AutoBoolAuto,
45 CollectOutputQueueTotals: confopt.AutoBoolAuto,
46
47 SlowPath: true,
48 SlowPathUpdateEvery: confopt.Duration(10 * time.Second),
49 SlowPathMaxConnections: 1,
50 BatchPath: false,
51 BatchPathUpdateEvery: confopt.Duration(60 * time.Second),
52 BatchPathMaxConnections: 1,
53
54 MaxDisks: 100,
55 MaxSubsystems: 100,
56
57 DiskSelector: "",
58 SubsystemSelector: "",
59 MessageQueues: []string{
60 "QSYS/QSYSOPR",
61 "QSYS/QSYSMSG",
62 "QSYS/QHST",
63 },
64 JobQueues: nil,
65 OutputQueues: nil,
66 ActiveJobs: nil,
67 }
68 }
69
70 func (c *Collector) Init(ctx context.Context) error {
71 c.initOnce()
72
73 // Propagate job-level configuration into framework collector
74 if c.Config.ObsoletionIterations != 0 {
75 c.Collector.Config.ObsoletionIterations = c.Config.ObsoletionIterations
76 }
77 if c.Config.UpdateEvery != 0 {
78 c.Collector.Config.UpdateEvery = c.Config.UpdateEvery
79 }
80 if c.Config.CollectionGroups != nil {
81 c.Collector.Config.CollectionGroups = c.Config.CollectionGroups
82 }
83
84 // Register generated contexts before base init
85 c.RegisterContexts(contexts.GetAllContexts()...)
86
87 // Initialise base collector
88 if err := c.Collector.Init(ctx); err != nil {
89 return err
90 }
91
92 // Collector implements the framework interface itself
93 c.SetImpl(c)
94
95 // Prepare DSN from individual parameters if necessary
96 c.Debugf("initial config: DSN=%q hostname=%q username=%q password_set=%t port=%d driver=%q",
97 c.DSN, c.Hostname, c.Username, c.Password != "", c.Port, c.ODBCDriver)
98 if err := c.buildDSNIfNeeded(ctx); err != nil {
99 return err
100 }
101 if err := c.verifyConfig(); err != nil {
102 return err
103 }
104
105 clientCfg := as400proto.Config{
106 DSN: c.DSN,
107 Timeout: time.Duration(c.Timeout),
108 MaxOpenConns: 1,
109 }
110 c.client = as400proto.NewClient(clientCfg)
111
112 if c.ResetStatistics {
113 c.Warningf("reset_statistics is enabled; IBM i statistics will be reset on each collection iteration")
114 }
115
116 // Compile selectors if provided
117 if c.DiskSelector != "" {
118 m, err := matcher.NewSimplePatternsMatcher(c.DiskSelector)
119 if err != nil {
120 return fmt.Errorf("invalid disk selector pattern '%s': %v", c.DiskSelector, err)
121 }
122 c.diskSelector = m
123 }
124 if c.SubsystemSelector != "" {
125 m, err := matcher.NewSimplePatternsMatcher(c.SubsystemSelector)
126 if err != nil {
127 return fmt.Errorf("invalid subsystem selector pattern '%s': %v", c.SubsystemSelector, err)
128 }
129 c.subsystemSelector = m
130 }
131 // Detect IBM i version on first init to drive feature toggles
132 if err := c.client.Connect(ctx); err == nil {
133 if err := c.detectIBMiVersion(ctx); err != nil {
134 c.Warningf("failed to detect IBM i version: %v", err)
135 } else {
136 c.Infof("detected IBM i version: %s", c.osVersion)
137 }
138
139 c.logVersionInformation()
140 c.setConfigurationDefaults()
141 c.detectAvailableFeatures(ctx)
142 c.collectSystemInfo(ctx)
143 c.applyGlobalLabels()
144 }
145
146 if err := c.configureTargets(); err != nil {
147 return err
148 }
149
150 if err := c.startSlowPath(); err != nil {
151 return err
152 }
153
154 if err := c.startBatchPath(); err != nil {
155 return err
156 }
157
158 return nil
159 }
160
161 func (c *Collector) applyGlobalLabels() {
162 labels := map[string]string{
163 "ibmi_version": c.osVersion,
164 "technology_refresh": c.technologyRefresh,
165 "system_name": c.systemName,
166 "serial_number": c.serialNumber,
167 "model": c.model,
168 }
169 c.SetGlobalLabels(labels)
170 }
171
172 func (c *Collector) Check(ctx context.Context) error {
173 c.initOnce()
174 if err := c.client.Connect(ctx); err != nil {
175 return err
176 }
177 if err := c.client.Ping(ctx); err != nil {
178 return err
179 }
180 // Perform lightweight query to ensure connectivity
181 return c.collect(ctx)
182 }