]> err.no Git - sope/blob - sope-appserver/NGObjWeb/WOStats.m
Revisited all copied resources in all Xcode projects. Ensured that all README, COPYIN...
[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/WORequest.h>
26 #include <NGObjWeb/WOResponse.h>
27 #include <NGObjWeb/WOSession.h>
28 #include <NGObjWeb/WOStatisticsStore.h>
29 #include "common.h"
30
31 @interface WOApplication(MemoryStatistics)
32
33 - (NSDictionary *)memoryStatistics;
34
35 @end
36
37 @implementation WOApplication(MemoryStatistics)
38
39 - (NSDictionary *)memoryStatistics {
40 #ifdef __linux__
41   FILE     *f;
42   char     buf[4096];
43   char     fname[256];
44   unsigned len;
45
46   sprintf(fname, "/proc/%d/status", getpid());
47   if ((f = fopen(fname, "r"))) {
48     id           d = nil;
49     NSString     *s;
50     NSEnumerator *lines;
51     
52     len = fread(buf, 1, sizeof(buf) - 1, f);
53     fclose(f);
54     buf[len] = '\0';
55
56     s = [NSString stringWithCString:buf];
57     lines = [[s componentsSeparatedByString:@"\n"] objectEnumerator];
58     while ((s = [lines nextObject])) {
59       NSString *key;
60       NSRange rng;
61
62       rng = [s rangeOfString:@":"];
63       if (rng.length <= 0)
64         continue;
65
66       key = [s substringToIndex:rng.location];
67
68       if ([key hasPrefix:@"Vm"]) {
69         const char *cstr;
70         id value;
71         
72         cstr = [s cString];
73         while (*cstr != '\0' && *cstr != ':') cstr++;
74         if (*cstr == '\0') continue;
75         cstr++;
76         while (*cstr != '\0' && isspace(*cstr)) cstr++;
77         value = [NSString stringWithCString:cstr];
78         
79         if ([value hasSuffix:@" kB"]) {
80           value = [value substringToIndex:[value length] - 3];
81           value = [NSNumber numberWithInt:[value intValue] * 1024];
82         }
83         
84         if (d == nil) d = [NSMutableDictionary dictionary];
85         [d setObject:value forKey:key];
86       }
87     }
88     return d;
89   }
90 #endif
91   return nil;
92 }
93
94 @end /* WOApplication(MemoryStatistics) */
95
96 @implementation WODirectAction(WOStats)
97
98 - (id<WOActionResults>)WOStatsAction {
99   WOApplication *app;
100   WOResponse   *response;
101   NSDictionary *stats;
102   NSString     *xslPath;
103   NSArray      *languages;
104   static NSDictionary *keyToDataType = nil;
105   
106   if (keyToDataType == nil) {
107     keyToDataType =
108       [[NSDictionary alloc] initWithObjectsAndKeys:
109                                   @"number", @"averageDuration",
110                                   @"number", @"maximumDuration",
111                                   @"number", @"minimumDuration",
112                                   @"number", @"totalDuration",
113                                   @"number", @"instanceUptime",
114                                   @"number", @"instanceUptimeInHours",
115                                   @"number", @"instanceLoad",
116                                   @"number", @"pageResponseCount",
117                                   @"number", @"numberOfZippedResponses",
118                                   @"number", @"totalResponseCount",
119                                   @"number", @"pageFrequency",
120                                   @"number", @"pageDeliveryVolumne",
121                                   @"number", @"responseFrequency",
122                                   @"number", @"relativeTimeConsumption",
123                                   @"number", @"averageResponseSize",
124                                   @"number", @"totalResponseSize",
125                                   @"number", @"totalZippedSize",
126                                   @"number", @"smallestResponseSize",
127                                   @"number", @"largestResponseSize",
128                                   @"number", @"VmData",
129                                   @"number", @"VmExe",
130                                   @"number", @"VmRSS",
131                                   @"number", @"VmLib",
132                                   @"number", @"VmStk",
133                                   @"number", @"VmSize",
134                                   @"number", @"VmLck",
135                                   nil];
136   }
137   
138   app = [WOApplication application];
139
140   xslPath = [[NSUserDefaults standardUserDefaults]
141                              stringForKey:@"WOStatsStylesheetName"];
142   languages = [self existingSession] != nil
143     ? [[self session] languages]
144     : [[self request] browserLanguages];
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 setHeader:@"text/xml" forKey:@"content-type"];
154   
155   stats = [[app statisticsStore] statistics];
156   
157   [response appendContentString:@"<?xml version='1.0'?>\n"];
158 #if 1
159   if ([xslPath length] > 0) {
160     [response appendContentString:@"<?xml-stylesheet type='text/xsl' href='"];
161     [response appendContentString:xslPath];
162     [response appendContentString:@"'?>"];
163   }
164 #endif
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) */