2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
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>
32 @interface WOApplication(MemoryStatistics)
34 - (NSDictionary *)memoryStatistics;
38 @implementation WOApplication(MemoryStatistics)
40 - (NSDictionary *)memoryStatistics {
47 sprintf(fname, "/proc/%d/status", getpid());
48 if ((f = fopen(fname, "r"))) {
53 len = fread(buf, 1, sizeof(buf) - 1, f);
57 s = [NSString stringWithCString:buf];
58 lines = [[s componentsSeparatedByString:@"\n"] objectEnumerator];
59 while ((s = [lines nextObject])) {
63 rng = [s rangeOfString:@":"];
67 key = [s substringToIndex:rng.location];
69 if ([key hasPrefix:@"Vm"]) {
74 while (*cstr != '\0' && *cstr != ':') cstr++;
75 if (*cstr == '\0') continue;
77 while (*cstr != '\0' && isspace(*cstr)) cstr++;
78 value = [NSString stringWithCString:cstr];
80 if ([value hasSuffix:@" kB"]) {
81 value = [value substringToIndex:[value length] - 3];
82 value = [NSNumber numberWithInt:[value intValue] * 1024];
86 d = [NSMutableDictionary dictionaryWithCapacity:16];
87 [(NSMutableDictionary *)d setObject:value forKey:key];
96 @end /* WOApplication(MemoryStatistics) */
98 @implementation WODirectAction(WOStats)
100 - (id<WOActionResults>)WOStatsAction {
102 WOResponse *response;
106 static NSDictionary *keyToDataType = nil;
108 if (keyToDataType == nil) {
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",
135 @"number", @"VmSize",
140 app = [WOApplication application];
142 xslPath = [[NSUserDefaults standardUserDefaults]
143 stringForKey:@"WOStatsStylesheetName"];
144 languages = [[self context] resourceLookupLanguages];
145 xslPath = [[app resourceManager] urlForResourceNamed:xslPath
148 request:[self request]];
149 if ([xslPath hasPrefix:@"/missingresource"])
152 response = [WOResponse responseWithRequest:[self request]];
153 [response setContentEncoding:NSUTF8StringEncoding];
154 [response setHeader:@"text/xml; charset=utf-8" forKey:@"content-type"];
156 stats = [[app statisticsStore] statistics];
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:@"'?>"];
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"];
176 NSDictionary *pageStatistics;
178 /* application statistics */
180 e = [stats keyEnumerator];
181 while ((key = [e nextObject])) {
185 if ([key isEqualToString:@"pageStatistics"])
188 value = [stats objectForKey:key];
190 [response appendContentString:@" <"];
191 [response appendContentString:key];
193 if ((dt = [keyToDataType objectForKey:key])) {
194 [response appendContentString:@" dt:dt='"];
195 [response appendContentString:dt];
196 [response appendContentString:@"'"];
199 [response appendContentString:@">"];
201 [response appendContentHTMLString:[value stringValue]];
203 [response appendContentString:@"</"];
204 [response appendContentString:key];
205 [response appendContentString:@">\n"];
208 /* memory statistics */
213 mem = [app memoryStatistics];
215 if ([mem count] > 0) {
216 [response appendContentString:@" <memory>\n"];
218 e = [mem keyEnumerator];
219 while ((key = [e nextObject])) {
223 value = [mem objectForKey:key];
225 [response appendContentString:@" <"];
226 [response appendContentString:key];
228 if ((dt = [keyToDataType objectForKey:key])) {
229 [response appendContentString:@" dt:dt='"];
230 [response appendContentString:dt];
231 [response appendContentString:@"'"];
234 [response appendContentString:@">"];
236 [response appendContentHTMLString:[value stringValue]];
238 [response appendContentString:@"</"];
239 [response appendContentString:key];
240 [response appendContentString:@">\n"];
243 [response appendContentString:@" </memory>\n"];
247 /* page statistics */
249 pageStatistics = [stats objectForKey:@"pageStatistics"];
251 [response appendContentString:@" <pages>\n"];
253 e = [pageStatistics keyEnumerator];
254 while ((key = [e nextObject])) {
259 stats = [pageStatistics objectForKey:key];
260 e2 = [stats keyEnumerator];
262 [response appendContentString:@" <page name='"];
263 [response appendContentString:key];
264 [response appendContentString:@"'>\n"];
266 while ((key2 = [e2 nextObject])) {
270 value = [stats objectForKey:key2];
272 [response appendContentString:@" <"];
273 [response appendContentString:key2];
275 if ((dt = [keyToDataType objectForKey:key2])) {
276 [response appendContentString:@" dt:dt='"];
277 [response appendContentString:dt];
278 [response appendContentString:@"'"];
281 [response appendContentString:@">"];
283 [response appendContentHTMLString:[value stringValue]];
285 [response appendContentString:@"</"];
286 [response appendContentString:key2];
287 [response appendContentString:@">\n"];
289 [response appendContentString:@" </page>\n"];
292 [response appendContentString:@" </pages>\n"];
295 [response appendContentString:@"</application>\n"];
300 @end /* WODirectAction(WOStats) */