a9249628709fbc47720c07679ed59f66b7ac1b4e
[public/netxms.git] / src / agent / subagents / bind9 / src / main / java / com / github / tomaskir / netxms / subagents / bind9 / collection / Collector.java
1 package com.github.tomaskir.netxms.subagents.bind9.collection;
2
3 import com.github.tomaskir.netxms.subagents.bind9.Parameters;
4 import com.github.tomaskir.netxms.subagents.bind9.exceptions.StatsFileRemovalException;
5 import lombok.Builder;
6 import org.netxms.agent.SubAgent;
7
8 import java.io.IOException;
9 import java.nio.charset.StandardCharsets;
10 import java.nio.file.Files;
11 import java.nio.file.NoSuchFileException;
12 import java.nio.file.Path;
13 import java.util.List;
14 import java.util.concurrent.locks.ReadWriteLock;
15
16 /**
17 * @author Tomas Kirnak
18 * @since 2.1-M1
19 */
20 public final class Collector implements Runnable {
21
22 private final long collectionInterval;
23 private final Path statsFile;
24 private final Parameters supportedParameters;
25 private final CollectionResult result;
26 private final ReadWriteLock dataCollectionLock;
27
28 private long lastCollection = 0;
29 private boolean threadRunning = true;
30
31 // constructor
32 @Builder
33 public Collector(long collectionInterval, Path statsFile, Parameters supportedParameters,
34 CollectionResult result, ReadWriteLock dataCollectionLock) {
35 this.collectionInterval = collectionInterval;
36 this.statsFile = statsFile;
37 this.supportedParameters = supportedParameters;
38 this.result = result;
39 this.dataCollectionLock = dataCollectionLock;
40 }
41
42 public void terminate() {
43 threadRunning = false;
44 }
45
46 @Override
47 public void run() {
48 long now;
49 Process rndc;
50 List<String> lines;
51
52 while (threadRunning) {
53 now = System.currentTimeMillis() / 1000;
54
55 if (now > lastCollection + collectionInterval) {
56 // remove existing statistics file
57 try {
58 statsFileCleanup();
59 } catch (StatsFileRemovalException e) {
60 SubAgent.writeLog(SubAgent.LogLevel.WARNING,
61 "Failed to delete bind9 statistics file, error: '" + e.getCause().getMessage() + "'");
62
63 result.setCollectionError(true);
64 updateLastCollectionTime();
65 continue;
66 }
67
68 // run "rndc stats" to generate new statistics file
69 try {
70 rndc = Runtime.getRuntime().exec("rndc stats");
71 } catch (IOException e) {
72 SubAgent.writeLog(SubAgent.LogLevel.ERROR,
73 "Failed to run 'rndc stats', error: '" + e.getMessage() + "'");
74
75 result.setCollectionError(true);
76 updateLastCollectionTime();
77 continue;
78 }
79
80 // wait for "rndc stats" to finish
81 try {
82 rndc.waitFor();
83 } catch (InterruptedException ignored) {
84 rndc.destroy();
85 continue;
86 }
87
88 // check for errors
89 if (rndc.exitValue() != 0) {
90 SubAgent.writeLog(SubAgent.LogLevel.ERROR,
91 "'rndc stats' exited with a non-0 exit code value");
92
93 result.setCollectionError(true);
94 updateLastCollectionTime();
95 continue;
96 }
97
98 // load stats from the stats file
99 try {
100 lines = Files.readAllLines(statsFile, StandardCharsets.UTF_8);
101 } catch (IOException e) {
102 SubAgent.writeLog(SubAgent.LogLevel.WARNING,
103 "Unable to read bind9 statistics file, error: '" + e.getMessage() + "'");
104
105 result.setCollectionError(true);
106 updateLastCollectionTime();
107 continue;
108 }
109
110 // lock data collection lock for writing
111 dataCollectionLock.writeLock().lock();
112
113 // remove previous values in result
114 result.getResult().clear();
115
116 // for every parameter supported by this plugin
117 for (String[] entry : supportedParameters.getList()) {
118 // search all lines
119 for (String line : lines) {
120 int index = line.indexOf(entry[2]);
121
122 // if attribute found
123 if (index != -1) {
124 // get value of the attribute
125 String value = line.substring(0, index).trim();
126
127 // insert into the result map
128 result.getResult().put(entry[0], value);
129
130 break;
131 }
132 }
133 }
134
135 result.setCollectionError(false);
136 updateLastCollectionTime();
137
138 // unlock data collection lock
139 dataCollectionLock.writeLock().unlock();
140 }
141
142 try {
143 Thread.sleep(100);
144 } catch (InterruptedException ignored) {
145 }
146 }
147 }
148
149 private void statsFileCleanup() throws StatsFileRemovalException {
150 try {
151 Files.delete(statsFile);
152 } catch (NoSuchFileException ignored) {
153 // if the file doesn't exist, we do nothing
154 } catch (IOException e) {
155 throw new StatsFileRemovalException(e);
156 }
157 }
158
159 private void updateLastCollectionTime() {
160 lastCollection = System.currentTimeMillis() / 1000;
161 }
162
163 }