3fbabf0da0a51e51017863f53e9dc2c542db3692
1 /**
2 *
3 * collectd - src/fhcount.c
4 * Copyright (c) 2015, Jiri Tyr <jiri.tyr at gmail.com>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 **/
20 #include "collectd.h"
22 #include "common.h"
23 #include "plugin.h"
25 static const char *config_keys[] = {"ValuesAbsolute", "ValuesPercentage"};
26 static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
28 static _Bool values_absolute = 1;
29 static _Bool values_percentage = 0;
31 static int fhcount_config(const char *key, const char *value) {
32 int ret = -1;
34 if (strcasecmp(key, "ValuesAbsolute") == 0) {
35 if (IS_TRUE(value)) {
36 values_absolute = 1;
37 } else {
38 values_absolute = 0;
39 }
41 ret = 0;
42 } else if (strcasecmp(key, "ValuesPercentage") == 0) {
43 if (IS_TRUE(value)) {
44 values_percentage = 1;
45 } else {
46 values_percentage = 0;
47 }
49 ret = 0;
50 }
52 return (ret);
53 }
55 static void fhcount_submit(const char *type, const char *type_instance,
56 gauge_t value) {
58 value_t values[1];
59 value_list_t vl = VALUE_LIST_INIT;
61 values[0].gauge = value;
63 vl.values = values;
64 vl.values_len = 1;
66 // Compose the metric
67 sstrncpy(vl.host, hostname_g, sizeof(vl.host));
68 sstrncpy(vl.plugin, "fhcount", sizeof(vl.plugin));
69 sstrncpy(vl.type, type, sizeof(vl.type));
70 sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
72 // Dispatch the metric
73 plugin_dispatch_values(&vl);
74 }
76 static int fhcount_read(void) {
77 int numfields = 0;
78 int buffer_len = 60;
79 gauge_t used, unused, max;
80 int prc_used, prc_unused;
81 char *fields[3];
82 char buffer[buffer_len];
83 char errbuf[1024];
84 FILE *fp;
86 // Open file
87 fp = fopen("/proc/sys/fs/file-nr", "r");
88 if (fp == NULL) {
89 ERROR("fhcount: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
90 return (EXIT_FAILURE);
91 }
92 if (fgets(buffer, buffer_len, fp) == NULL) {
93 ERROR("fhcount: fgets: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
94 fclose(fp);
95 return (EXIT_FAILURE);
96 }
97 fclose(fp);
99 // Tokenize string
100 numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields));
102 if (numfields != 3) {
103 ERROR("fhcount: Line doesn't contain 3 fields");
104 return (EXIT_FAILURE);
105 }
107 // Define the values
108 strtogauge(fields[0], &used);
109 strtogauge(fields[1], &unused);
110 strtogauge(fields[2], &max);
111 prc_used = (gauge_t)used / max * 100;
112 prc_unused = (gauge_t)unused / max * 100;
114 // Submit values
115 if (values_absolute) {
116 fhcount_submit("file_handles", "used", (gauge_t)used);
117 fhcount_submit("file_handles", "unused", (gauge_t)unused);
118 fhcount_submit("file_handles", "max", (gauge_t)max);
119 }
120 if (values_percentage) {
121 fhcount_submit("percent", "used", (gauge_t)prc_used);
122 fhcount_submit("percent", "unused", (gauge_t)prc_unused);
123 }
125 return (0);
126 }
128 void module_register(void) {
129 plugin_register_config("fhcount", fhcount_config, config_keys,
130 config_keys_num);
131 plugin_register_read("fhcount", fhcount_read);
132 }