]> err.no Git - sope/blob - sope-appserver/NGObjWeb/WOStats.m
fixed bundle resource lookup on MacOSX, changed resource lookup in
[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) d = [NSMutableDictionary dictionary];
86         [d setObject:value forKey:key];
87       }
88     }
89     return d;
90   }
91 #endif
92   return nil;
93 }
94
95 @end /* WOApplication(MemoryStatistics) */
96
97 @implementation WODirectAction(WOStats)
98
99 - (id<WOActionResults>)WOStatsAction {
100   WOApplication *app;
101   WOResponse   *response;
102   NSDictionary *stats;
103   NSString     *xslPath;
104   NSArray      *languages;
105   static NSDictionary *keyToDataType = nil;
106   
107   if (keyToDataType == nil) {
108     keyToDataType =
109       [[NSDictionary alloc] initWithObjectsAndKeys:
110                                   @"number", @"averageDuration",
111                                   @"number", @"maximumDuration",
112                                   @"number", @"minimumDuration",
113                                   @"number", @"totalDuration",
114                                   @"number", @"instanceUptime",
115                                   @"number", @"instanceUptimeInHours",
116                                   @"number", @"instanceLoad",
117                                   @"number", @"pageResponseCount",
118                                   @"number", @"numberOfZippedResponses",
119                                   @"number", @"totalResponseCount",
120                                   @"number", @"pageFrequency",
121                                   @"number", @"pageDeliveryVolumne",
122                                   @"number", @"responseFrequency",
123                                   @"number", @"relativeTimeConsumption",
124                                   @"number", @"averageResponseSize",
125                                   @"number", @"totalResponseSize",
126                                   @"number", @"totalZippedSize",
127                                   @"number", @"smallestResponseSize",
128                                   @"number", @"largestResponseSize",
129                                   @"number", @"VmData",
130                                   @"number", @"VmExe",
131                                   @"number", @"VmRSS",
132                                   @"number", @"VmLib",
133                                   @"number", @"VmStk",
134                                   @"number", @"VmSize",
135                                   @"number", @"VmLck",
136                                   nil];
137   }
138   
139   app = [WOApplication application];
140
141   xslPath = [[NSUserDefaults standardUserDefaults]
142                              stringForKey:@"WOStatsStylesheetName"];
143   languages = [[self context] resourceLookupLanguages];
144   xslPath   = [[app resourceManager] urlForResourceNamed:xslPath
145                                      inFramework:nil
146                                      languages:languages
147                                      request:[self request]];
148   if ([xslPath hasPrefix:@"/missingresource"])
149     xslPath = nil;
150   
151   response = [WOResponse responseWithRequest:[self request]];
152   [response setHeader:@"text/xml" forKey:@"content-type"];
153   
154   stats = [[app statisticsStore] statistics];
155   
156   [response appendContentString:@"<?xml version='1.0'?>\n"];
157 #if 1
158   if ([xslPath length] > 0) {
159     [response appendContentString:@"<?xml-stylesheet type='text/xsl' href='"];
160     [response appendContentString:xslPath];
161     [response appendContentString:@"'?>"];
162   }
163 #endif
164   [response appendContentString:@"<application name='"];
165   [response appendContentString:[app name]];
166   [response appendContentString:@"'"];
167   [response appendContentString:
168               [NSString stringWithFormat:@" pid='%d'", getpid()]];
169   [response appendContentString:
170               @" xmlns:dt='urn:schemas-microsoft-com:datatypes'>\n"];
171   
172   {
173     NSEnumerator *e;
174     NSString *key;
175     NSDictionary *pageStatistics;
176     
177     /* application statistics */
178     
179     e = [stats keyEnumerator];
180     while ((key = [e nextObject])) {
181       id value;
182       NSString *dt;
183       
184       if ([key isEqualToString:@"pageStatistics"])
185         continue;
186
187       value = [stats objectForKey:key];
188       
189       [response appendContentString:@"  <"];
190       [response appendContentString:key];
191         
192       if ((dt = [keyToDataType objectForKey:key])) {
193         [response appendContentString:@" dt:dt='"];
194         [response appendContentString:dt];
195         [response appendContentString:@"'"];
196       }
197       
198       [response appendContentString:@">"];
199       
200       [response appendContentHTMLString:[value stringValue]];
201       
202       [response appendContentString:@"</"];
203       [response appendContentString:key];
204       [response appendContentString:@">\n"];
205     }
206
207     /* memory statistics */
208
209     {
210       NSDictionary *mem;
211       
212       mem = [app memoryStatistics];
213
214       if ([mem count] > 0) {
215         [response appendContentString:@"  <memory>\n"];
216         
217         e = [mem keyEnumerator];
218         while ((key = [e nextObject])) {
219           id       value;
220           NSString *dt;
221
222           value = [mem objectForKey:key];
223           
224           [response appendContentString:@"  <"];
225           [response appendContentString:key];
226         
227           if ((dt = [keyToDataType objectForKey:key])) {
228             [response appendContentString:@" dt:dt='"];
229             [response appendContentString:dt];
230             [response appendContentString:@"'"];
231           }
232       
233           [response appendContentString:@">"];
234       
235           [response appendContentHTMLString:[value stringValue]];
236       
237           [response appendContentString:@"</"];
238           [response appendContentString:key];
239           [response appendContentString:@">\n"];
240         }
241
242         [response appendContentString:@"  </memory>\n"];
243       }
244     }
245
246     /* page statistics */
247     
248     pageStatistics = [stats objectForKey:@"pageStatistics"];
249
250     [response appendContentString:@"  <pages>\n"];
251     
252     e = [pageStatistics keyEnumerator];
253     while ((key = [e nextObject])) {
254       NSDictionary *stats;
255       NSEnumerator *e2;
256       NSString     *key2;
257       
258       stats = [pageStatistics objectForKey:key];
259       e2    = [stats keyEnumerator];
260       
261       [response appendContentString:@"    <page name='"];
262       [response appendContentString:key];
263       [response appendContentString:@"'>\n"];
264       
265       while ((key2 = [e2 nextObject])) {
266         id value;
267         NSString *dt;
268
269         value = [stats objectForKey:key2];
270         
271         [response appendContentString:@"      <"];
272         [response appendContentString:key2];
273         
274         if ((dt = [keyToDataType objectForKey:key2])) {
275           [response appendContentString:@" dt:dt='"];
276           [response appendContentString:dt];
277           [response appendContentString:@"'"];
278         }
279         
280         [response appendContentString:@">"];
281         
282         [response appendContentHTMLString:[value stringValue]];
283         
284         [response appendContentString:@"</"];
285         [response appendContentString:key2];
286         [response appendContentString:@">\n"];
287       }
288       [response appendContentString:@"    </page>\n"];
289     }
290     
291     [response appendContentString:@"  </pages>\n"];
292   }
293   
294   [response appendContentString:@"</application>\n"];
295   
296   return response;
297 }
298
299 @end /* WODirectAction(WOStats) */