zfs_arc plugin: Introduce the single-valued "cache_eviction" type.
[collectd.git] / src / zfs_arc.c
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  **/
21
22 #include "collectd.h"
23 #include "common.h"
24 #include "plugin.h"
25
26 /*
27  * Global variables
28  */
29 static kstat_t *ksp;
30 extern kstat_ctl_t *kc;
31
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;
35
36         vl.values = values;
37         vl.values_len = values_len;
38
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));
43
44         plugin_dispatch_values (&vl);
45 }
46
47 static void za_submit_gauge (const char* type, const char* type_instance, gauge_t value)
48 {
49         value_t vv;
50
51         vv.gauge = value;
52         za_submit (type, type_instance, &vv, 1);
53 }
54
55 static void za_submit_derive (const char* type, const char* type_instance, derive_t dv)
56 {
57         value_t vv;
58
59         vv.derive = dv;
60         za_submit (type, type_instance, &vv, 1);
61 }
62
63 static void za_submit_ratio (const char* type_instance, gauge_t hits, gauge_t misses)
64 {
65         gauge_t ratio = NAN;
66
67         if (!isfinite (hits) || (hits < 0.0))
68                 hits = 0.0;
69         if (!isfinite (misses) || (misses < 0.0))
70                 misses = 0.0;
71
72         if ((hits != 0.0) || (misses != 0.0))
73                 ratio = hits / (hits + misses);
74
75         za_submit_gauge ("cache_ratio", type_instance, ratio);
76 }
77
78 static void za_submit_mutex_counts (derive_t mutex_miss)
79 {
80         value_t values[1];
81
82         values[0].counter = mutex_miss;
83
84         za_submit ("mutex", "counts", values, STATIC_ARRAY_SIZE(values));
85 }
86
87 static void za_submit_deleted_counts (derive_t deleted)
88 {
89         value_t values[1];
90
91         values[0].counter = deleted;
92
93         za_submit ("deleted", "counts", values, STATIC_ARRAY_SIZE(values));
94 }
95
96 static void za_submit_hash_counts (derive_t hash_collisions)
97 {
98         value_t values[1];
99
100         values[0].counter = hash_collisions;
101
102         za_submit ("hash", "counts", values, STATIC_ARRAY_SIZE(values));
103 }
104
105 static int za_read (void)
106 {
107         gauge_t  arc_size, l2_size;
108         derive_t demand_data_hits,
109                  demand_metadata_hits,
110                  prefetch_data_hits,
111                  prefetch_metadata_hits,
112                  demand_data_misses,
113                  demand_metadata_misses,
114                  prefetch_data_misses,
115                  prefetch_metadata_misses;
116         gauge_t  arc_hits, arc_misses, l2_hits, l2_misses;
117         value_t  l2_io[2];
118         derive_t mutex_miss;
119         derive_t deleted;
120         derive_t evict_l2_cached, evict_l2_eligible, evict_l2_ineligible;
121         derive_t hash_collisions;
122
123         get_kstat (&ksp, "zfs", 0, "arcstats");
124         if (ksp == NULL)
125         {
126                 ERROR ("zfs_arc plugin: Cannot find zfs:0:arcstats kstat.");
127                 return (-1);
128         }
129
130         /* Sizes */
131         arc_size   = get_kstat_value(ksp, "size");
132         l2_size    = get_kstat_value(ksp, "l2_size");
133
134         za_submit_gauge ("cache_size", "arc", arc_size);
135         za_submit_gauge ("cache_size", "L2", l2_size);
136
137         mutex_miss               = get_kstat_value(ksp, "mutex_miss"); 
138
139         deleted                  = get_kstat_value(ksp, "deleted");
140         
141         evict_l2_cached          = get_kstat_value(ksp, "evict_l2_cached");
142         evict_l2_eligible        = get_kstat_value(ksp, "evict_l2_eligible");
143         evict_l2_ineligible      = get_kstat_value(ksp, "evict_l2_ineligible");
144         
145         za_submit_derive ("cache_eviction", "cached",     evict_l2_cached);
146         za_submit_derive ("cache_eviction", "eligible",   evict_l2_eligible);
147         za_submit_derive ("cache_eviction", "ineligible", evict_l2_ineligible);
148
149         hash_collisions          = get_kstat_value(ksp, "hash_collisions");
150
151         /* Hits / misses */
152         demand_data_hits       = get_kstat_value(ksp, "demand_data_hits");
153         demand_metadata_hits   = get_kstat_value(ksp, "demand_metadata_hits");
154         prefetch_data_hits     = get_kstat_value(ksp, "prefetch_data_hits");
155         prefetch_metadata_hits = get_kstat_value(ksp, "prefetch_metadata_hits");
156
157         demand_data_misses       = get_kstat_value(ksp, "demand_data_misses");
158         demand_metadata_misses   = get_kstat_value(ksp, "demand_metadata_misses");
159         prefetch_data_misses     = get_kstat_value(ksp, "prefetch_data_misses");
160         prefetch_metadata_misses = get_kstat_value(ksp, "prefetch_metadata_misses");
161
162         za_submit_derive ("cache_result", "demand_data-hit",       demand_data_hits);
163         za_submit_derive ("cache_result", "demand_metadata-hit",   demand_metadata_hits);
164         za_submit_derive ("cache_result", "prefetch_data-hit",     prefetch_data_hits);
165         za_submit_derive ("cache_result", "prefetch_metadata-hit", prefetch_metadata_hits);
166
167         za_submit_derive ("cache_result", "demand_data-miss",       demand_data_misses);
168         za_submit_derive ("cache_result", "demand_metadata-miss",   demand_metadata_misses);
169         za_submit_derive ("cache_result", "prefetch_data-miss",     prefetch_data_misses);
170         za_submit_derive ("cache_result", "prefetch_metadata-miss", prefetch_metadata_misses);
171
172         /* Ratios */
173         arc_hits   = (gauge_t) get_kstat_value(ksp, "hits");
174         arc_misses = (gauge_t) get_kstat_value(ksp, "misses");
175         l2_hits    = (gauge_t) get_kstat_value(ksp, "l2_hits");
176         l2_misses  = (gauge_t) get_kstat_value(ksp, "l2_misses");
177
178         za_submit_ratio ("arc", arc_hits, arc_misses);
179         za_submit_ratio ("L2", l2_hits, l2_misses);
180
181         /* I/O */
182         l2_io[0].derive = get_kstat_value(ksp, "l2_read_bytes");
183         l2_io[1].derive = get_kstat_value(ksp, "l2_write_bytes");
184
185         za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
186
187         za_submit_mutex_counts (mutex_miss);
188
189         za_submit_deleted_counts (deleted);
190
191         za_submit_hash_counts (deleted);
192
193         return (0);
194 } /* int za_read */
195
196 static int za_init (void) /* {{{ */
197 {
198         ksp = NULL;
199
200         /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */
201         if (kc == NULL)
202         {
203                 ERROR ("zfs_arc plugin: kstat chain control structure not available.");
204                 return (-1);
205         }
206
207         return (0);
208 } /* }}} int za_init */
209
210 void module_register (void)
211 {
212         plugin_register_init ("zfs_arc", za_init);
213         plugin_register_read ("zfs_arc", za_read);
214 } /* void module_register */
215
216 /* vmi: set sw=8 noexpandtab fdm=marker : */