]> err.no Git - sope/blob - sope-appserver/NGObjWeb/WOStats.m
fixed gcc 4.0 warnings
[sope] / sope-appserver / NGObjWeb / WOStats.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 #include <NGObjWeb/WODirectAction.h>
23 #include <NGObjWeb/WOApplication.h>
24 #include <NGObjWeb/WOResourceManager.h>
25 #include <NGObjWeb/WOContext.h>
26 #include <NGObjWeb/WORequest.h>
27 #include <NGObjWeb/WOResponse.h>
28 #include <NGObjWeb/WOSession.h>
29 #include <NGObjWeb/WOStatisticsStore.h>
30 #include "common.h"
31
32 @interface WOApplication(MemoryStatistics)
33
34 - (NSDictionary *)memoryStatistics;
35
36 @end
37
38 @implementation WOApplication(MemoryStatistics)
39
40 - (NSDictionary *)memoryStatistics {
41 #ifdef __linux__
42   FILE     *f;
43   char     buf[4096];
44   char     fname[256];
45   unsigned len;
46
47   sprintf(fname, "/proc/%d/status", getpid());
48   if ((f = fopen(fname, "r"))) {
49     id           d = nil;
50     NSString     *s;
51     NSEnumerator *lines;
52     
53     len = fread(buf, 1, sizeof(buf) - 1, f);
54     fclose(f);
55     buf[len] = '\0';
56
57     s = [NSString stringWithCString:buf];
58     lines = [[s componentsSeparatedByString:@"\n"] objectEnumerator];
59     while ((s = [lines nextObject])) {
60       NSString *key;
61       NSRange rng;
62
63       rng = [s rangeOfString:@":"];
64       if (rng.length <= 0)
65         continue;
66
67       key = [s substringToIndex:rng.location];
68
69       if ([key hasPrefix:@"Vm"]) {
70         const char *cstr;
71         id value;
72         
73         cstr = [s cString];
74         while (*cstr != '\0' && *cstr != ':') cstr++;
75         if (*cstr == '\0') continue;
76         cstr++;
77         while (*cstr != '\0' && isspace(*cstr)) cstr++;
78         value = [NSString stringWithCString:cstr];
79         
80         if ([value hasSuffix:@" kB"]) {
81           value = [value substringToIndex:[value length] - 3];
82           value = [NSNumber numberWithInt:[value intValue] * 1024];
83         }
84         
85         if (d == nil) 
86           d = [NSMutableDictionary dictionaryWithCapacity:16];
87         [(NSMutableDictionary *)d setObject:value forKey:key];
88       }
89     }
90     return d;
91   }
92 #endif
93   return nil;
94 }
95
96 @end /* WOApplication(MemoryStatistics) */
97
98 @implementation WODirectAction(WOStats)
99
100 - (id<WOActionResults>)WOStatsAction {
101   WOApplication *app;
102   WOResponse   *response;
103   NSDictionary *stats;
104   NSString     *xslPath;
105   NSArray      *languages;
106   static NSDictionary *keyToDataType = nil;
107   
108   if (keyToDataType == nil) {
109     keyToDataType =
110       [[NSDictionary alloc] initWithObjectsAndKeys:
111                                   @"number", @"averageDuration",
112                                   @"number", @"maximumDuration",
113                                   @"number", @"minimumDuration",
114                                   @"number", @"totalDuration",
115                                   @"number", @"instanceUptime",
116                                   @"number", @"instanceUptimeInHours",
117                                   @"number", @"instanceLoad",
118                                   @"number", @"pageResponseCount",
119                                   @"number", @"numberOfZippedResponses",
120                                   @"number", @"totalResponseCount",
121                                   @"number", @"pageFrequency",
122                                   @"number", @"pageDeliveryVolumne",
123                                   @"number", @"responseFrequency",
124                                   @"number", @"relativeTimeConsumption",
125                                   @"number", @"averageResponseSize",
126                                   @"number", @"totalResponseSize",
127                                   @"number", @"totalZippedSize",
128                                   @"number", @"smallestResponseSize",
129                                   @"number", @"largestResponseSize",
130                                   @"number", @"VmData",
131                                   @"number", @"VmExe",
132                                   @"number", @"VmRSS",
133                                   @"number", @"VmLib",
134                                   @"number", @"VmStk",
135                                   @"number", @"VmSize",
136                                   @"number", @"VmLck",
137                                   nil];
138   }
139   
140   app = [WOApplication application];
141
142   xslPath = [[NSUserDefaults standardUserDefaults]
143                              stringForKey:@"WOStatsStylesheetName"];
144   languages = [[self context] resourceLookupLanguages];
145   xslPath   = [[app resourceManager] urlForResourceNamed:xslPath
146                                      inFramework:nil
147                                      languages:languages
148                                      request:[self request]];
149   if ([xslPath hasPrefix:@"/missingresource"])
150     xslPath = nil;
151   
152   response = [WOResponse responseWithRequest:[self request]];
153   [response setContentEncoding:NSUTF8StringEncoding];
154   [response setHeader:@"text/xml; charset=utf-8" forKey:@"content-type"];
155   
156   stats = [[app statisticsStore] statistics];
157   
158   [response appendContentString:@"<?xml version='1.0'?>\n"];
159   if ([xslPath length] > 0) {
160     [response appendContentString:@"<?xml-stylesheet type='text/xsl' href='"];
161     [response appendContentString:xslPath];
162     [response appendContentString:@"'?>"];
163   }
164
165   [response appendContentString:@"<application name='"];
166   [response appendContentString:[app name]];
167   [response appendContentString:@"'"];
168   [response appendContentString:
169               [NSString stringWithFormat:@" pid='%d'", getpid()]];
170   [response appendContentString:
171               @" xmlns:dt='urn:schemas-microsoft-com:datatypes'>\n"];
172   
173   {
174     NSEnumerator *e;
175     NSString *key;
176     NSDictionary *pageStatistics;
177     
178     /* application statistics */
179     
180     e = [stats keyEnumerator];
181     while ((key = [e nextObject])) {
182       id value;
183       NSString *dt;
184       
185       if ([key isEqualToString:@"pageStatistics"])
186         continue;
187
188       value = [stats objectForKey:key];
189       
190       [response appendContentString:@"  <"];
191       [response appendContentString:key];
192         
193       if ((dt = [keyToDataType objectForKey:key])) {
194         [response appendContentString:@" dt:dt='"];
195         [response appendContentString:dt];
196         [response appendContentString:@"'"];
197       }
198       
199       [response appendContentString:@">"];
200       
201       [response appendContentHTMLString:[value stringValue]];
202       
203       [response appendContentString:@"</"];
204       [response appendContentString:key];
205       [response appendContentString:@">\n"];
206     }
207
208     /* memory statistics */
209
210     {
211       NSDictionary *mem;
212       
213       mem = [app memoryStatistics];
214
215       if ([mem count] > 0) {
216         [response appendContentString:@"  <memory>\n"];
217         
218         e = [mem keyEnumerator];
219         while ((key = [e nextObject])) {
220           id       value;
221           NSString *dt;
222
223           value = [mem objectForKey:key];
224           
225           [response appendContentString:@"  <"];
226           [response appendContentString:key];
227         
228           if ((dt = [keyToDataType objectForKey:key])) {
229             [response appendContentString:@" dt:dt='"];
230             [response appendContentString:dt];
231             [response appendContentString:@"'"];
232           }
233       
234           [response appendContentString:@">"];
235       
236           [response appendContentHTMLString:[value stringValue]];
237       
238           [response appendContentString:@"</"];
239           [response appendContentString:key];
240           [response appendContentString:@">\n"];
241         }
242
243         [response appendContentString:@"  </memory>\n"];
244       }
245     }
246
247     /* page statistics */
248     
249     pageStatistics = [stats objectForKey:@"pageStatistics"];
250
251     [response appendContentString:@"  <pages>\n"];
252     
253     e = [pageStatistics keyEnumerator];
254     while ((key = [e nextObject])) {
255       NSDictionary *stats;
256       NSEnumerator *e2;
257       NSString     *key2;
258       
259       stats = [pageStatistics objectForKey:key];
260       e2    = [stats keyEnumerator];
261       
262       [response appendContentString:@"    <page name='"];
263       [response appendContentString:key];
264       [response appendContentString:@"'>\n"];
265       
266       while ((key2 = [e2 nextObject])) {
267         id value;
268         NSString *dt;
269
270         value = [stats objectForKey:key2];
271         
272         [response appendContentString:@"      <"];
273         [response appendContentString:key2];
274         
275         if ((dt = [keyToDataType objectForKey:key2])) {
276           [response appendContentString:@" dt:dt='"];
277           [response appendContentString:dt];
278           [response appendContentString:@"'"];
279         }
280         
281         [response appendContentString:@">"];
282         
283         [response appendContentHTMLString:[value stringValue]];
284         
285         [response appendContentString:@"</"];
286         [response appendContentString:key2];
287         [response appendContentString:@">\n"];
288       }
289       [response appendContentString:@"    </page>\n"];
290     }
291     
292     [response appendContentString:@"  </pages>\n"];
293   }
294   
295   [response appendContentString:@"</application>\n"];
296   
297   return response;
298 }
299
300 @end /* WODirectAction(WOStats) */