Logo ROOT  
Reference Guide
httptextlog.C File Reference

Detailed Description

This macro demonstrates custom access and custom drawing for TMsgList class Main motivation for this example - demonstrate how traffic between server and client can be minimized and how one could build custom UI in the browser

TMsgList in this tutorial keep last N messages, numbering each with unique identifier There is TMsgList::Select() method which selects messages from the list If one specifies identifier, only messages newer than this identifier are selected In the selection list (TList object of TObjString) first item always identifier for the latest message in the list

In JavaScript code (httptextlog.js) one uses Select() method to receive latest messages, which not yet been seen in the browser and display them as text At maximum, 1000 elements are preserved in the browser.

Macro should always be started in compiled mode, otherwise Select() method is not accessible via TClass instance. One also requires comments after ClassDef to correctly configure behavior of the JavaScript ROOT code

After macro started, one could open in browser address

http://localhost:8080?item=log

One could either click item again or enable monitoring to always receive latest messages Or one could open only this output and nothing else:

http://localhost:8080/log/draw.htm?monitoring=2000

In last case it could be used in iframe, also it requires less code to load on the page

#include <stdio.h>
#include <string.h>
#include "TNamed.h"
#include "TList.h"
#include "TObjString.h"
#include "TH1.h"
#include "TH2.h"
#include "TRandom3.h"
#include "TSystem.h"
#include "THttpServer.h"
#include "TRootSniffer.h"
#include "TDatime.h"
#include "TClass.h"
Bool_t bRun = kTRUE;
class TMsgList : public TNamed {
protected:
TList fMsgs; // list messages, stored as TObjString
Int_t fLimit; // max number of stored messages
Long64_t fCounter; // current message id
TList fSelect; //! temporary list used for selection
TObjString fStrCounter; //! current id stored in the string
public:
TMsgList(const char* name = "log", Int_t limit = 1000) :
TNamed(name,"list of log messages"),
fMsgs(),
fLimit(limit),
fCounter(0),
fSelect(),
fStrCounter()
{
fMsgs.SetOwner(kTRUE);
// counter initialized from current time
// if application restarted, id will be bigger and request from browser
// will not lead to messages lost. Of course, if more than 1000 messages
// per second are generated, one could have mismatch
fCounter = ((Long64_t) TDatime().Get()) * 1000;
}
virtual ~TMsgList() { fMsgs.Clear(); }
void AddMsg(const char* msg)
{
// add message to the list
// if number of stored messages bigger than configured, old messages will be removed
// zero (msg==0) messages will not be add to the list
while (fMsgs.GetSize() >= fLimit) {
TObject* last = fMsgs.Last();
fMsgs.RemoveLast();
delete last;
}
if (msg==0) return;
fMsgs.AddFirst(new TObjString(msg));
fCounter++;
}
TList* Select(Int_t max = 0, Long64_t id = 0)
{
// Central method to select new messages
// Current id stored as first item and used on the client to request new portion
// One could limit number of returned messages
TIter iter(&fMsgs);
TObject* obj = 0;
Long64_t curr = fCounter;
fSelect.Clear();
if (max == 0) max = fMsgs.GetLast()+1;
// add current id as first string in the list
fStrCounter.SetString(TString::LLtoa(fCounter, 10));
fSelect.Add(&fStrCounter);
while (((obj = iter()) != 0) && (--curr >= id) && (--max>=0)) fSelect.Add(obj);
return &fSelect;
}
ClassDef(TMsgList, 1); // Custom messages list
};
void httptextlog()
{
// create logging instance
TMsgList* log = new TMsgList("log", 200);
if ((TMsgList::Class()->GetMethodAllAny("Select") == 0) || (strcmp(log->ClassName(), "TMsgList")!=0)) {
printf("Most probably, macro runs in interpreter mode\n");
printf("To access new methods from TMsgList class,\n");
printf("one should run macro with ACLiC like:\n");
printf(" shell> root -b httpextlog.C+\n");
return;
}
if (gSystem->AccessPathName("httptextlog.js")!=0) {
printf("Please start macro from directory where httptextlog.js is available\n");
printf("Only in this case web interface can work\n");
return;
}
// create histograms, just for fun
TH1D *hpx = new TH1D("hpx","This is the px distribution",100,-4,4);
hpx->SetFillColor(48);
hpx->SetDirectory(0);
TH2F *hpxpy = new TH2F("hpxpy","py vs px",40,-4,4,40,-4,4);
hpxpy->SetDirectory(0);
// start http server
THttpServer* serv = new THttpServer("http:8080");
// One could specify location of newer version of JSROOT
// serv->SetJSROOT("https://root.cern.ch/js/latest/");
// serv->SetJSROOT("http://jsroot.gsi.de/latest/");
// let always load httptextlog.js script in the browser
serv->GetSniffer()->SetAutoLoad("currentdir/httptextlog.js");
// register histograms
serv->Register("/", hpx);
serv->Register("/", hpxpy);
// register log instance
serv->Register("/", log);
// while server runs in read-only mode, we should allow methods execution
serv->Restrict("/log", "allow_method=Select,GetTitle");
// register exit command
serv->RegisterCommand("/Stop","bRun=kFALSE;", "rootsys/icons/ed_delete.png");
serv->RegisterCommand("/ExitRoot","gSystem->Exit(1);", "rootsys/icons/ed_delete.png");
// Fill histograms randomly
TRandom3 random;
Float_t px, py;
const Long_t kUPDATE = 1000;
Long_t cnt = 0;
while (bRun) {
random.Rannor(px,py);
hpx->Fill(px);
hpxpy->Fill(px,py);
// IMPORTANT: one should regularly call ProcessEvents
if (cnt++ % kUPDATE == 0) {
if (gSystem->ProcessEvents()) break;
Long_t loop = cnt / kUPDATE;
// make messages not very often
if (loop % 1000 == 0) {
loop = loop/1000;
int shift = loop % 40;
// make a 'stairs' with spaces
log->AddMsg(TString::Format("%*s Message %ld", shift, "", loop));
}
}
}
delete serv; // delete http server
}
Author
Sergey Linev

Definition in file httptextlog.C.

TList::RemoveLast
virtual void RemoveLast()
Remove the last object of the list.
Definition: TList.cxx:908
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TList::AddFirst
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:99
TDatime::Get
UInt_t Get() const
Return raw date/time as encoded by TDatime.
Definition: TDatime.cxx:240
THttpServer::GetSniffer
TRootSniffer * GetSniffer() const
returns pointer on objects sniffer
Definition: THttpServer.h:82
THttpServer::Restrict
void Restrict(const char *path, const char *options)
Restrict access to specified object.
Definition: THttpServer.cxx:1118
TH2F
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
TObjString.h
TDatime.h
TNamed.h
Long64_t
long long Long64_t
Definition: RtypesCore.h:73
TCollection::SetOwner
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Definition: TCollection.cxx:746
TH1D
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:615
Float_t
float Float_t
Definition: RtypesCore.h:57
log
double log(double)
Int_t
int Int_t
Definition: RtypesCore.h:45
TClass.h
TList.h
TList::Last
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:692
TObjString::SetString
void SetString(const char *s)
Definition: TObjString.h:51
TString::Format
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
TSystem::AccessPathName
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1294
Bool_t
bool Bool_t
Definition: RtypesCore.h:63
TRandom::Rannor
virtual void Rannor(Float_t &a, Float_t &b)
Return 2 numbers distributed following a gaussian with mean=0 and sigma=1.
Definition: TRandom.cxx:489
TObjString
Definition: TObjString.h:28
THttpServer
Definition: THttpServer.h:31
TSystem.h
TRandom3
Definition: TRandom3.h:27
THttpServer::Register
Bool_t Register(const char *subfolder, TObject *obj)
Register object in subfolder.
Definition: THttpServer.cxx:980
TNamed
Definition: TNamed.h:29
Long_t
long Long_t
Definition: RtypesCore.h:54
TH1::Fill
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3274
TRandom3.h
TH1::SetDirectory
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8392
TH2.h
TH2::Fill
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:294
TRootSniffer.h
gSystem
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
THttpServer.h
TString::LLtoa
static TString LLtoa(Long64_t value, Int_t base)
Converts a Long64_t to a TString with respect to the base specified (2-36).
Definition: TString.cxx:2077
TCollection::GetSize
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
TList::Add
virtual void Add(TObject *obj)
Definition: TList.h:87
TObject
Definition: TObject.h:37
ClassDef
#define ClassDef(name, id)
Definition: Rtypes.h:325
TList::Clear
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:401
name
char name[80]
Definition: TGX11.cxx:110
THttpServer::RegisterCommand
Bool_t RegisterCommand(const char *cmdname, const char *method, const char *icon=0)
Register command which can be executed from web interface.
Definition: THttpServer.cxx:1151
kUPDATE
@ kUPDATE
Definition: TFitParametersDialog.cxx:51
TIter
Definition: TCollection.h:233
TDatime
Definition: TDatime.h:37
xmlio::cnt
const char * cnt
Definition: TXMLSetup.cxx:81
Class
void Class()
Definition: Class.C:29
TSeqCollection::GetLast
virtual Int_t GetLast() const
Returns index of last object in collection.
Definition: TSeqCollection.cxx:47
TH1.h
TSystem::ProcessEvents
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:417
TList
Definition: TList.h:44
TRootSniffer::SetAutoLoad
void SetAutoLoad(const char *scripts="")
When specified, _autoload attribute will be always add to top element of h.json/h....
Definition: TRootSniffer.cxx:478