4bd9e5b631753880bdba3a79b87712026b9c1668
[rrdtool.git] / src / rrd_stat.c
1 /*****************************************************************************
2  * RRDtool 1.2.23  Copyright by Tobi Oetiker, 1997-2007
3  *****************************************************************************
4  * rrd_stat Retreive the header part of an RRD
5  *****************************************************************************/
6
7 #include "rrd_tool.h"
8
9 XXX:This file is not compiled.Is this on purpose ? extern char *tzname[2];
10
11 stat_node rrd_stat(
12     int argc,
13     char **argv)
14 {
15     int       i, ii, ix, iii = 0;
16     time_t    now;
17     char      somestring[255];
18     rrd_value_t my_cdp;
19     long      rra_base, rra_start, rra_next;
20     rrd_t     rrd;
21     rrd_file_t *rrd_file;
22
23
24     rrd_file = rrd_open(argv[1], &rrd, RRD_READONLY);
25     if (rrd_file == NULL) {
26         return (-1);
27     }
28     puts("<!-- Round Robin Database Dump -->");
29     puts("<rrd>");
30     printf("\t<version> %s </version>\n", rrd.stat_head->version);
31     printf("\t<step> %lu </step> <!-- Seconds -->\n",
32            rrd.stat_head->pdp_step);
33 #if HAVE_STRFTIME
34     strftime(somestring, 200, "%Y-%m-%d %H:%M:%S %Z",
35              localtime_r(&rrd.live_head->last_up, &tm));
36 #else
37 # error "Need strftime"
38 #endif
39     printf("\t<lastupdate> %ld </lastupdate> <!-- %s -->\n\n",
40            rrd.live_head->last_up, somestring);
41     for (i = 0; i < rrd.stat_head->ds_cnt; i++) {
42         printf("\t<ds>\n");
43         printf("\t\t<name> %s </name>\n", rrd.ds_def[i].ds_nam);
44         printf("\t\t<type> %s </type>\n", rrd.ds_def[i].dst);
45         printf("\t\t<minimal_heartbeat> %lu </minimal_heartbeat>\n",
46                rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt);
47         if (isnan(rrd.ds_def[i].par[DS_min_val].u_val)) {
48             printf("\t\t<min> NaN </min>\n");
49         } else {
50             printf("\t\t<min> %0.10e </min>\n",
51                    rrd.ds_def[i].par[DS_min_val].u_val);
52         }
53         if (isnan(rrd.ds_def[i].par[DS_max_val].u_val)) {
54             printf("\t\t<max> NaN </max>\n");
55         } else {
56             printf("\t\t<max> %0.10e </max>\n",
57                    rrd.ds_def[i].par[DS_max_val].u_val);
58         }
59         printf("\n\t\t<!-- PDP Status -->\n");
60         printf("\t\t<last_ds> %s </last_ds>\n", rrd.pdp_prep[i].last_ds);
61         if (isnan(rrd.pdp_prep[i].scratch[PDP_val].u_val)) {
62             printf("\t\t<value> NaN </value>\n");
63         } else {
64             printf("\t\t<value> %0.10e </value>\n",
65                    rrd.pdp_prep[i].scratch[PDP_val].u_val);
66         }
67         printf("\t\t<unknown_sec> %lu </unknown_sec>\n",
68                rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
69
70         printf("\t</ds>\n\n");
71     }
72
73     puts("<!-- Round Robin Archives -->");
74
75     rra_base = rrd_file->header_len;
76     rra_next = rra_base;
77
78     for (i = 0; i < rrd.stat_head->rra_cnt; i++) {
79
80         long      timer = 0;
81
82         rra_start = rra_next;
83         rra_next += (rrd.stat_head->ds_cnt
84                      * rrd.rra_def[i].row_cnt * sizeof(rrd_value_t));
85         printf("\t<rra>\n");
86         printf("\t\t<cf> %s </cf>\n", rrd.rra_def[i].cf_nam);
87         printf
88             ("\t\t<pdp_per_row> %lu </pdp_per_row> <!-- %lu seconds -->\n\n",
89              rrd.rra_def[i].pdp_cnt,
90              rrd.rra_def[i].pdp_cnt * rrd.stat_head->pdp_step);
91         printf("\t\t<cdp_prep>\n");
92         for (ii = 0; ii < rrd.stat_head->ds_cnt; ii++) {
93             double    value =
94                 rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
95                              ii].scratch[CDP_val].u_val;
96             printf("\t\t\t<ds>");
97             if (isnan(value)) {
98                 printf("<value> NaN </value>");
99             } else {
100                 printf("<value> %0.10e </value>", value);
101             }
102             printf("  <unknown_datapoints> %lu </unknown_datapoints>",
103                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
104                                 ii].scratch[CDP_unkn_pdp_cnt].u_cnt);
105             printf("</ds>\n");
106         }
107         printf("\t\t</cdp_prep>\n");
108
109         printf("\t\t<database>\n");
110         rrd_seek(rrd_file, (rra_start + (rrd.rra_ptr[i].cur_row + 1)
111                             * rrd.stat_head->ds_cnt
112                             * sizeof(rrd_value_t)), SEEK_SET);
113         timer = -(rrd.rra_def[i].row_cnt - 1);
114         ii = rrd.rra_ptr[i].cur_row;
115         for (ix = 0; ix < rrd.rra_def[i].row_cnt; ix++) {
116             ii++;
117             if (ii >= rrd.rra_def[i].row_cnt) {
118                 rrd_seek(rrd_file, rra_start, SEEK_SET);
119                 ii = 0; /* wrap if max row cnt is reached */
120             }
121             now = (rrd.live_head->last_up
122                    - rrd.live_head->last_up
123                    % (rrd.rra_def[i].pdp_cnt * rrd.stat_head->pdp_step))
124                 + (timer * rrd.rra_def[i].pdp_cnt * rrd.stat_head->pdp_step);
125
126             timer++;
127 #if HAVE_STRFTIME
128             strftime(somestring, 200, "%Y-%m-%d %H:%M:%S %Z",
129                      localtime_r(&now, &tm));
130 #else
131 # error "Need strftime"
132 #endif
133             printf("\t\t\t<!-- %s --> <row>", somestring);
134             for (iii = 0; iii < rrd.stat_head->ds_cnt; iii++) {
135                 rrd_read(rrd_file, &my_cdp, sizeof(rrd_value_t) * 1);
136                 if (isnan(my_cdp)) {
137                     printf("<v> NaN </v>");
138                 } else {
139                     printf("<v> %0.10e </v>", my_cdp);
140                 };
141             }
142             printf("</row>\n");
143         }
144         printf("\t\t</database>\n\t</rra>\n");
145
146     }
147     printf("</rrd>\n");
148     rrd_free(&rrd);
149     close(rrd_file->fd);
150     return (0);
151 }