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/WORequest.h>
26 #include <NGObjWeb/WOResponse.h>
27 #include <NGObjWeb/WOSession.h>
28 #include <NGObjWeb/WOStatisticsStore.h>
31 @interface WOApplication(MemoryStatistics)
33 - (NSDictionary *)memoryStatistics;
37 @implementation WOApplication(MemoryStatistics)
39 - (NSDictionary *)memoryStatistics {
46 sprintf(fname, "/proc/%d/status", getpid());
47 if ((f = fopen(fname, "r"))) {
52 len = fread(buf, 1, sizeof(buf) - 1, f);
56 s = [NSString stringWithCString:buf];
57 lines = [[s componentsSeparatedByString:@"\n"] objectEnumerator];
58 while ((s = [lines nextObject])) {
62 rng = [s rangeOfString:@":"];
66 key = [s substringToIndex:rng.location];
68 if ([key hasPrefix:@"Vm"]) {
73 while (*cstr != '\0' && *cstr != ':') cstr++;
74 if (*cstr == '\0') continue;
76 while (*cstr != '\0' && isspace(*cstr)) cstr++;
77 value = [NSString stringWithCString:cstr];
79 if ([value hasSuffix:@" kB"]) {
80 value = [value substringToIndex:[value length] - 3];
81 value = [NSNumber numberWithInt:[value intValue] * 1024];
84 if (d == nil) d = [NSMutableDictionary dictionary];
85 [d setObject:value forKey:key];
94 @end /* WOApplication(MemoryStatistics) */
96 @implementation WODirectAction(WOStats)
98 - (id<WOActionResults>)WOStatsAction {
100 WOResponse *response;
104 static NSDictionary *keyToDataType = nil;
106 if (keyToDataType == nil) {
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",
133 @"number", @"VmSize",
138 app = [WOApplication application];
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
148 request:[self request]];
149 if ([xslPath hasPrefix:@"/missingresource"])
152 response = [WOResponse responseWithRequest:[self request]];
153 [response setHeader:@"text/xml" forKey:@"content-type"];
155 stats = [[app statisticsStore] statistics];
157 [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) */