1 /**
2 * collectd - src/zfs_arc.c
3 * Copyright (C) 2009 Anthony Dewhurst
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Authors:
19 * Anthony Dewhurst <dewhurst at gmail>
20 **/
22 #include "collectd.h"
23 #include "common.h"
24 #include "plugin.h"
26 /*
27 * Global variables
28 */
29 static kstat_t *ksp;
30 extern kstat_ctl_t *kc;
32 static void za_submit (const char* type, const char* type_instance, value_t* values, int values_len)
33 {
34 value_list_t vl = VALUE_LIST_INIT;
36 vl.values = values;
37 vl.values_len = values_len;
39 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
40 sstrncpy (vl.plugin, "zfs_arc", sizeof (vl.plugin));
41 sstrncpy (vl.type, type, sizeof (vl.type));
42 sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
44 plugin_dispatch_values (&vl);
45 }
47 static void za_submit_gauge (const char* type, const char* type_instance, gauge_t value)
48 {
49 value_t vv;
51 vv.gauge = value;
52 za_submit (type, type_instance, &vv, 1);
53 }
55 static void za_submit_derive (const char* type, const char* type_instance, derive_t dv)
56 {
57 value_t vv;
59 vv.derive = dv;
60 za_submit (type, type_instance, &vv, 1);
61 }
63 static void za_submit_ratio (const char* type_instance, gauge_t hits, gauge_t misses)
64 {
65 gauge_t ratio = NAN;
67 if (!isfinite (hits) || (hits < 0.0))
68 hits = 0.0;
69 if (!isfinite (misses) || (misses < 0.0))
70 misses = 0.0;
72 if ((hits != 0.0) || (misses != 0.0))
73 ratio = hits / (hits + misses);
75 za_submit_gauge ("cache_ratio", type_instance, ratio);
76 }
78 static void za_submit_evict_counts (counter_t evict_l2_cached, counter_t evict_l2_eligible,
79 counter_t evict_l2_ineligible)
80 {
81 value_t values[3];
83 values[0].counter = evict_l2_cached;
84 values[1].counter = evict_l2_eligible;
85 values[2].counter = evict_l2_ineligible;
87 za_submit ("evict", "counts", values, STATIC_ARRAY_SIZE(values));
88 }
90 static void za_submit_mutex_counts (counter_t mutex_miss)
91 {
92 value_t values[1];
94 values[0].counter = mutex_miss;
96 za_submit ("mutex", "counts", values, STATIC_ARRAY_SIZE(values));
97 }
99 static void za_submit_deleted_counts (counter_t deleted)
100 {
101 value_t values[1];
103 values[0].counter = deleted;
105 za_submit ("deleted", "counts", values, STATIC_ARRAY_SIZE(values));
106 }
108 static void za_submit_hash_counts (counter_t hash_collisions)
109 {
110 value_t values[1];
112 values[0].counter = hash_collisions;
114 za_submit ("hash", "counts", values, STATIC_ARRAY_SIZE(values));
115 }
117 static int za_read (void)
118 {
119 gauge_t arc_size, l2_size;
120 derive_t demand_data_hits,
121 demand_metadata_hits,
122 prefetch_data_hits,
123 prefetch_metadata_hits,
124 demand_data_misses,
125 demand_metadata_misses,
126 prefetch_data_misses,
127 prefetch_metadata_misses;
128 gauge_t arc_hits, arc_misses, l2_hits, l2_misses;
129 value_t l2_io[2];
130 counter_t mutex_miss;
131 counter_t deleted;
132 counter_t evict_l2_cached, evict_l2_eligible, evict_l2_ineligible;
133 counter_t hash_collisions;
135 get_kstat (&ksp, "zfs", 0, "arcstats");
136 if (ksp == NULL)
137 {
138 ERROR ("zfs_arc plugin: Cannot find zfs:0:arcstats kstat.");
139 return (-1);
140 }
142 /* Sizes */
143 arc_size = get_kstat_value(ksp, "size");
144 l2_size = get_kstat_value(ksp, "l2_size");
146 za_submit_gauge ("cache_size", "arc", arc_size);
147 za_submit_gauge ("cache_size", "L2", l2_size);
149 mutex_miss = get_kstat_value(ksp, "mutex_miss");
151 deleted = get_kstat_value(ksp, "deleted");
153 evict_l2_cached = get_kstat_value(ksp, "evict_l2_cached");
154 evict_l2_eligible = get_kstat_value(ksp, "evict_l2_eligible");
155 evict_l2_ineligible = get_kstat_value(ksp, "evict_l2_ineligible");
157 hash_collisions = get_kstat_value(ksp, "hash_collisions");
159 /* Hits / misses */
160 demand_data_hits = get_kstat_value(ksp, "demand_data_hits");
161 demand_metadata_hits = get_kstat_value(ksp, "demand_metadata_hits");
162 prefetch_data_hits = get_kstat_value(ksp, "prefetch_data_hits");
163 prefetch_metadata_hits = get_kstat_value(ksp, "prefetch_metadata_hits");
165 demand_data_misses = get_kstat_value(ksp, "demand_data_misses");
166 demand_metadata_misses = get_kstat_value(ksp, "demand_metadata_misses");
167 prefetch_data_misses = get_kstat_value(ksp, "prefetch_data_misses");
168 prefetch_metadata_misses = get_kstat_value(ksp, "prefetch_metadata_misses");
170 za_submit_derive ("cache_result", "demand_data-hit", demand_data_hits);
171 za_submit_derive ("cache_result", "demand_metadata-hit", demand_metadata_hits);
172 za_submit_derive ("cache_result", "prefetch_data-hit", prefetch_data_hits);
173 za_submit_derive ("cache_result", "prefetch_metadata-hit", prefetch_metadata_hits);
175 za_submit_derive ("cache_result", "demand_data-miss", demand_data_misses);
176 za_submit_derive ("cache_result", "demand_metadata-miss", demand_metadata_misses);
177 za_submit_derive ("cache_result", "prefetch_data-miss", prefetch_data_misses);
178 za_submit_derive ("cache_result", "prefetch_metadata-miss", prefetch_metadata_misses);
180 /* Ratios */
181 arc_hits = (gauge_t) get_kstat_value(ksp, "hits");
182 arc_misses = (gauge_t) get_kstat_value(ksp, "misses");
183 l2_hits = (gauge_t) get_kstat_value(ksp, "l2_hits");
184 l2_misses = (gauge_t) get_kstat_value(ksp, "l2_misses");
186 za_submit_ratio ("arc", arc_hits, arc_misses);
187 za_submit_ratio ("L2", l2_hits, l2_misses);
189 /* I/O */
190 l2_io[0].derive = get_kstat_value(ksp, "l2_read_bytes");
191 l2_io[1].derive = get_kstat_value(ksp, "l2_write_bytes");
193 za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
195 za_submit_evict_counts (evict_l2_cached, evict_l2_eligible, evict_l2_ineligible);
197 za_submit_mutex_counts (mutex_miss);
199 za_submit_deleted_counts (deleted);
201 za_submit_hash_counts (deleted);
203 return (0);
204 } /* int za_read */
206 static int za_init (void) /* {{{ */
207 {
208 ksp = NULL;
210 /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */
211 if (kc == NULL)
212 {
213 ERROR ("zfs_arc plugin: kstat chain control structure not available.");
214 return (-1);
215 }
217 return (0);
218 } /* }}} int za_init */
220 void module_register (void)
221 {
222 plugin_register_init ("zfs_arc", za_init);
223 plugin_register_read ("zfs_arc", za_read);
224 } /* void module_register */
226 /* vmi: set sw=8 noexpandtab fdm=marker : */