]> err.no Git - sope/blob - sope-appserver/NGObjWeb/WOStats.m
added svn:keywords and svn:ignore where appropriate. removed CVS artifacts.
[sope] / sope-appserver / NGObjWeb / WOStats.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo 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   OGo 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 OGo; 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 // $Id$
22
23 #include <NGObjWeb/WODirectAction.h>
24 #include <NGObjWeb/WOApplication.h>
25 #include <NGObjWeb/WOResourceManager.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 existingSession] != nil
144     ? [[self session] languages]
145     : [[self request] browserLanguages];
146   xslPath = [[app resourceManager] urlForResourceNamed:xslPath
147                                    inFramework:nil
148                                    languages:languages
149                                    request:[self request]];
150   if ([xslPath hasPrefix:@"/missingresource"])
151     xslPath = nil;
152   
153   response = [WOResponse responseWithRequest:[self request]];
154   [response setHeader:@"text/xml" forKey:@"content-type"];
155   
156   stats = [[app statisticsStore] statistics];
157   
158   [response appendContentString:@"<?xml version='1.0'?>\n"];
159 #if 1
160   if ([xslPath length] > 0) {
161     [response appendContentString:@"<?xml-stylesheet type='text/xsl' href='"];
162     [response appendContentString:xslPath];
163     [response appendContentString:@"'?>"];
164   }
165 #endif
166   [response appendContentString:@"<application name='"];
167   [response appendContentString:[app name]];
168   [response appendContentString:@"'"];
169   [response appendContentString:
170               [NSString stringWithFormat:@" pid='%d'", getpid()]];
171   [response appendContentString:
172               @" xmlns:dt='urn:schemas-microsoft-com:datatypes'>\n"];
173   
174   {
175     NSEnumerator *e;
176     NSString *key;
177     NSDictionary *pageStatistics;
178     
179     /* application statistics */
180     
181     e = [stats keyEnumerator];
182     while ((key = [e nextObject])) {
183       id value;
184       NSString *dt;
185       
186       if ([key isEqualToString:@"pageStatistics"])
187         continue;
188
189       value = [stats objectForKey:key];
190       
191       [response appendContentString:@"  <"];
192       [response appendContentString:key];
193         
194       if ((dt = [keyToDataType objectForKey:key])) {
195         [response appendContentString:@" dt:dt='"];
196         [response appendContentString:dt];
197         [response appendContentString:@"'"];
198       }
199       
200       [response appendContentString:@">"];
201       
202       [response appendContentHTMLString:[value stringValue]];
203       
204       [response appendContentString:@"</"];
205       [response appendContentString:key];
206       [response appendContentString:@">\n"];
207     }
208
209     /* memory statistics */
210
211     {
212       NSDictionary *mem;
213       
214       mem = [app memoryStatistics];
215
216       if ([mem count] > 0) {
217         [response appendContentString:@"  <memory>\n"];
218         
219         e = [mem keyEnumerator];
220         while ((key = [e nextObject])) {
221           id       value;
222           NSString *dt;
223
224           value = [mem objectForKey:key];
225           
226           [response appendContentString:@"  <"];
227           [response appendContentString:key];
228         
229           if ((dt = [keyToDataType objectForKey:key])) {
230             [response appendContentString:@" dt:dt='"];
231             [response appendContentString:dt];
232             [response appendContentString:@"'"];
233           }
234       
235           [response appendContentString:@">"];
236       
237           [response appendContentHTMLString:[value stringValue]];
238       
239           [response appendContentString:@"</"];
240           [response appendContentString:key];
241           [response appendContentString:@">\n"];
242         }
243
244         [response appendContentString:@"  </memory>\n"];
245       }
246     }
247
248     /* page statistics */
249     
250     pageStatistics = [stats objectForKey:@"pageStatistics"];
251
252     [response appendContentString:@"  <pages>\n"];
253     
254     e = [pageStatistics keyEnumerator];
255     while ((key = [e nextObject])) {
256       NSDictionary *stats;
257       NSEnumerator *e2;
258       NSString     *key2;
259       
260       stats = [pageStatistics objectForKey:key];
261       e2    = [stats keyEnumerator];
262       
263       [response appendContentString:@"    <page name='"];
264       [response appendContentString:key];
265       [response appendContentString:@"'>\n"];
266       
267       while ((key2 = [e2 nextObject])) {
268         id value;
269         NSString *dt;
270
271         value = [stats objectForKey:key2];
272         
273         [response appendContentString:@"      <"];
274         [response appendContentString:key2];
275         
276         if ((dt = [keyToDataType objectForKey:key2])) {
277           [response appendContentString:@" dt:dt='"];
278           [response appendContentString:dt];
279           [response appendContentString:@"'"];
280         }
281         
282         [response appendContentString:@">"];
283         
284         [response appendContentHTMLString:[value stringValue]];
285         
286         [response appendContentString:@"</"];
287         [response appendContentString:key2];
288         [response appendContentString:@">\n"];
289       }
290       [response appendContentString:@"    </page>\n"];
291     }
292     
293     [response appendContentString:@"  </pages>\n"];
294   }
295   
296   [response appendContentString:@"</application>\n"];
297   
298   return response;
299 }
300
301 @end /* WODirectAction(WOStats) */