MODULE WebDefaultSSMP;
IMPORT
Machine, Streams, Modules, WebSSMPPlugin, Clock, WebHTTP,
WebHTTPServer, Performance, Reflection, Kernel;
CONST Samples = 60;
TYPE
TimeSampleQueryMethod = PROCEDURE {DELEGATE} () : LONGINT;
TimeSampler = OBJECT
VAR
hits : POINTER TO ARRAY OF LONGINT;
pos : LONGINT;
timer : Kernel.Timer;
query : TimeSampleQueryMethod;
interval, nofSamples : LONGINT;
alive : BOOLEAN;
PROCEDURE &Init*(queryMethod : TimeSampleQueryMethod; interval, samples : LONGINT);
BEGIN
NEW(timer); SELF.interval := interval; SELF.nofSamples := samples; SELF.query := queryMethod; NEW(hits, samples)
END Init;
PROCEDURE Step;
BEGIN {EXCLUSIVE}
hits^[pos] := query();
INC(pos); pos := pos MOD nofSamples
END Step;
PROCEDURE QuerySamples(VAR x : ARRAY OF LONGINT);
VAR i : LONGINT;
BEGIN {EXCLUSIVE}
FOR i := 0 TO nofSamples - 1 DO
x[i] := hits[(pos + i) MOD nofSamples]
END
END QuerySamples;
PROCEDURE Kill;
BEGIN
alive := FALSE; timer.Wakeup; timer.Wakeup
END Kill;
BEGIN {ACTIVE}
alive := TRUE; pos := 0;
WHILE alive DO
Step; IF alive THEN timer.Sleep(interval) END
END
END TimeSampler;
VAR hitSampler : TimeSampler;
PROCEDURE HTMLBarChartVertical(VAR out : Streams.Writer; samples : ARRAY OF LONGINT; start, end : LONGINT;
chartheight, barwidth, border, color: LONGINT);
VAR i, v : LONGINT;
BEGIN
IF chartheight <= 0 THEN chartheight := 100 END;
IF barwidth <= 0 THEN barwidth := 20 END;
out.String('<table border="'); out.Int(border, 0);
out.String('" height="'); out.Int(chartheight, 0); out.String('">'); out.Ln;
out.String('<tr valign="bottom">'); out.Ln;
FOR i := start TO end DO
out.String('<td><table border="0" cellspacing="0" width="');
out.Int(barwidth, 0);
out.String('" height="');
v := (samples[i] * chartheight) DIV 100;
out.Int(v, 0);
out.String('" bgcolor="#'); out.Hex(color, 6);
out.String('" ><tr><td></td></tr></table></td>');
out.Ln;
END;
out.String('</tr>'); out.Ln;
out.String('</table>'); out.Ln
END HTMLBarChartVertical;
PROCEDURE ServerNofRequests(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
BEGIN
out.Int(WebHTTPServer.GetRequests(), 5)
END ServerNofRequests;
PROCEDURE ServerRPMChart(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
VAR values : ARRAY 60 OF LONGINT; max: LONGINT; i : LONGINT;
BEGIN
hitSampler.QuerySamples(values);
FOR i := 0 TO 60 - 1 DO IF max < values[i] THEN max := values[i] END END;
IF max = 0 THEN max := 1 END;
FOR i := 0 TO 60 - 1 DO values[i] := values[i] * 100 DIV max END;
HTMLBarChartVertical(out, values, 0, 60-1, 100, 5, 0, 0FF0000H)
END ServerRPMChart;
PROCEDURE ServerNofRequestsPerMinute(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
BEGIN
out.Int(WebHTTPServer.requestsPerMinute, 5)
END ServerNofRequestsPerMinute;
PROCEDURE SystemTime(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
VAR time, date: LONGINT;
BEGIN
Clock.Get(time, date); out.Date822(time, date, Clock.tz);
END SystemTime;
PROCEDURE SystemStartTime(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
BEGIN
out.Date822(Clock.starttime, Clock.startdate, Clock.tz)
END SystemStartTime;
PROCEDURE SystemLoad(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
VAR x, i: LONGINT;
BEGIN
FOR i := 0 TO 2 DO
x := ENTIER(Performance.load[i]*100 + 0.5);
out.Int(x DIV 100, 3); out.Char(".");
out.Int(x DIV 10 MOD 10, 1); out.Int(x MOD 10, 1)
END
END SystemLoad;
PROCEDURE SystemIdle(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
VAR i: LONGINT;
BEGIN
i := 0;
WHILE (i < LEN(Performance.idle)) & (Performance.idle[i] > - 1) DO
out.Int(Performance.idle[i], 3); out.Char("%"); out.Char(" ");
INC(i)
END
END SystemIdle;
PROCEDURE SystemVersion(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
BEGIN
out.String(Machine.version)
END SystemVersion;
PROCEDURE ReadName(VAR b: Streams.Reader; VAR s: ARRAY OF CHAR);
VAR j, max: LONGINT; ch: CHAR;
BEGIN
j := 0; max := LEN(s)-1;
LOOP
ch := b.Peek();
IF ~(((CAP(ch) >= "A") & (CAP(ch) <= "Z")) OR ((ch >= "0") & (ch <= "9"))) OR (b.res # Streams.Ok) THEN EXIT END;
IF j < max THEN s[j] := ch; INC(j) END;
ch := b.Get()
END;
s[j] := 0X
END ReadName;
PROCEDURE SystemState(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
VAR name: ARRAY 32 OF CHAR;
BEGIN
in.SkipWhitespace; ReadName(in, name);
Reflection.ModuleState(out, Modules.ModuleByName(name))
END SystemState;
PROCEDURE SystemGet(VAR request : WebHTTP.RequestHeader; VAR in : Streams.Reader; VAR out : Streams.Writer);
VAR v: Reflection.Variable; col: LONGINT; mod, var: ARRAY 32 OF CHAR;
BEGIN
in.SkipWhitespace;
ReadName(in, mod);
IF in.Peek() = "." THEN
in.Char(var[0]);
ReadName(in, var);
IF Reflection.FindVar(Modules.ModuleByName(mod), var, v) THEN
Reflection.WriteVar(out, v, col)
ELSE
out.String("System.Get "); out.String(mod); out.Char(".");
out.String(var); out.String(": variable not found")
END
ELSE
out.String("usage: System.Get module.variable")
END
END SystemGet;
PROCEDURE Install*;
BEGIN
WebSSMPPlugin.RegisterMethod("Server.NofRequests", ServerNofRequests);
WebSSMPPlugin.RegisterMethod("Server.NofRequestsPerMinute", ServerNofRequestsPerMinute);
WebSSMPPlugin.RegisterMethod("System.Time", SystemTime);
WebSSMPPlugin.RegisterMethod("System.StartTime", SystemStartTime);
WebSSMPPlugin.RegisterMethod("System.Load", SystemLoad);
WebSSMPPlugin.RegisterMethod("System.Idle", SystemIdle);
WebSSMPPlugin.RegisterMethod("System.Version", SystemVersion);
WebSSMPPlugin.RegisterMethod("Server.RPMChart", ServerRPMChart);
WebSSMPPlugin.RegisterMethod("System.State", SystemState);
WebSSMPPlugin.RegisterMethod("System.Get", SystemGet);
END Install;
PROCEDURE Cleanup;
BEGIN
hitSampler.Kill;
WebSSMPPlugin.UnregisterMethod("Server.NofRequests");
WebSSMPPlugin.UnregisterMethod("Server.NofRequestsPerMinute");
WebSSMPPlugin.UnregisterMethod("System.Time");
WebSSMPPlugin.UnregisterMethod("System.StartTime");
WebSSMPPlugin.UnregisterMethod("System.Load");
WebSSMPPlugin.UnregisterMethod("System.Idle");
WebSSMPPlugin.UnregisterMethod("System.Version");
WebSSMPPlugin.UnregisterMethod("Server.RPMChart");
WebSSMPPlugin.UnregisterMethod("System.State");
WebSSMPPlugin.UnregisterMethod("System.Get")
END Cleanup;
PROCEDURE QueryRPM():LONGINT;
BEGIN
RETURN WebHTTPServer.requestsPerMinute
END QueryRPM;
BEGIN
NEW(hitSampler, QueryRPM, 10000, 60);
Modules.InstallTermHandler(Cleanup);
END WebDefaultSSMP.
EditTools.OpenUnix public.info.ssmp
EditTools.OpenUnix public.test.ssmp
System.Free WebDefaultSSMP~
Aos.Call WebDefaultSSMP.Install~