Logo ROOT  
Reference Guide
httptextlog.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_http
3/// This macro demonstrates custom access and custom drawing for TMsgList class
4/// Main motivation for this example - demonstrate how traffic between server and
5/// client can be minimized and how one could build custom UI in the browser
6///
7/// TMsgList in this tutorial keep last N messages, numbering each with unique identifier
8/// There is TMsgList::Select() method which selects messages from the list
9/// If one specifies identifier, only messages newer than this identifier are selected
10/// In the selection list (TList object of TObjString) first item always identifier for
11/// the latest message in the list
12///
13/// In JavaScript code (httptextlog.js) one uses Select() method to receive latest
14/// messages, which not yet been seen in the browser and display them as text
15/// At maximum, 1000 elements are preserved in the browser.
16///
17/// Macro should always be started in compiled mode, otherwise Select() method is not
18/// accessible via TClass instance. One also requires comments after ClassDef to
19/// correctly configure behavior of the JavaScript ROOT code
20///
21/// After macro started, one could open in browser address
22/// ~~~
23/// http://localhost:8080?item=log
24/// ~~~
25/// One could either click item again or enable monitoring to always receive latest messages
26/// Or one could open only this output and nothing else:
27/// ~~~
28/// http://localhost:8080/log/draw.htm?monitoring=2000
29/// ~~~
30/// In last case it could be used in iframe, also it requires less code to load on the page
31///
32/// \macro_code
33///
34/// \author Sergey Linev
35
36
37#include <stdio.h>
38#include <string.h>
39
40#include "TNamed.h"
41#include "TList.h"
42#include "TObjString.h"
43#include "TH1.h"
44#include "TH2.h"
45#include "TRandom3.h"
46#include "TSystem.h"
47#include "THttpServer.h"
48#include "TRootSniffer.h"
49#include "TDatime.h"
50#include "TClass.h"
51
52Bool_t bRun = kTRUE;
53
54class TMsgList : public TNamed {
55
56 protected:
57
58 TList fMsgs; // list messages, stored as TObjString
59 Int_t fLimit; // max number of stored messages
60 Long64_t fCounter; // current message id
61 TList fSelect; //! temporary list used for selection
62 TObjString fStrCounter; //! current id stored in the string
63
64 public:
65
66 TMsgList(const char* name = "log", Int_t limit = 1000) :
67 TNamed(name,"list of log messages"),
68 fMsgs(),
69 fLimit(limit),
70 fCounter(0),
71 fSelect(),
72 fStrCounter()
73 {
74 fMsgs.SetOwner(kTRUE);
75
76 // counter initialized from current time
77 // if application restarted, id will be bigger and request from browser
78 // will not lead to messages lost. Of course, if more than 1000 messages
79 // per second are generated, one could have mismatch
80
81 fCounter = ((Long64_t) TDatime().Get()) * 1000;
82 }
83
84 virtual ~TMsgList() { fMsgs.Clear(); }
85
86 void AddMsg(const char* msg)
87 {
88 // add message to the list
89 // if number of stored messages bigger than configured, old messages will be removed
90 // zero (msg==0) messages will not be add to the list
91
92 while (fMsgs.GetSize() >= fLimit) {
93 TObject* last = fMsgs.Last();
94 fMsgs.RemoveLast();
95 delete last;
96 }
97 if (msg==0) return;
98
99 fMsgs.AddFirst(new TObjString(msg));
100 fCounter++;
101 }
102
103 TList* Select(Int_t max = 0, Long64_t id = 0)
104 {
105 // Central method to select new messages
106 // Current id stored as first item and used on the client to request new portion
107 // One could limit number of returned messages
108
109 TIter iter(&fMsgs);
110 TObject* obj = 0;
111 Long64_t curr = fCounter;
112 fSelect.Clear();
113
114 if (max == 0) max = fMsgs.GetLast()+1;
115
116 // add current id as first string in the list
117 fStrCounter.SetString(TString::LLtoa(fCounter, 10));
118 fSelect.Add(&fStrCounter);
119
120 while (((obj = iter()) != 0) && (--curr >= id) && (--max>=0)) fSelect.Add(obj);
121
122 return &fSelect;
123 }
124
125 ClassDef(TMsgList, 1); // Custom messages list
126};
127
128void httptextlog()
129{
130 // create logging instance
131 TMsgList* log = new TMsgList("log", 200);
132
133 if ((TMsgList::Class()->GetMethodAllAny("Select") == 0) || (strcmp(log->ClassName(), "TMsgList")!=0)) {
134 printf("Most probably, macro runs in interpreter mode\n");
135 printf("To access new methods from TMsgList class,\n");
136 printf("one should run macro with ACLiC like:\n");
137 printf(" shell> root -b httpextlog.C+\n");
138 return;
139 }
140
141 if (gSystem->AccessPathName("httptextlog.js")!=0) {
142 printf("Please start macro from directory where httptextlog.js is available\n");
143 printf("Only in this case web interface can work\n");
144 return;
145 }
146
147 // create histograms, just for fun
148 TH1D *hpx = new TH1D("hpx","This is the px distribution",100,-4,4);
149 hpx->SetFillColor(48);
150 hpx->SetDirectory(0);
151 TH2F *hpxpy = new TH2F("hpxpy","py vs px",40,-4,4,40,-4,4);
152 hpxpy->SetDirectory(0);
153
154 // start http server
155 THttpServer* serv = new THttpServer("http:8080");
156
157 // One could specify location of newer version of JSROOT
158 // serv->SetJSROOT("https://root.cern.ch/js/latest/");
159 // serv->SetJSROOT("http://jsroot.gsi.de/latest/");
160
161 // let always load httptextlog.js script in the browser
162 serv->GetSniffer()->SetAutoLoad("currentdir/httptextlog.js");
163
164 // register histograms
165 serv->Register("/", hpx);
166 serv->Register("/", hpxpy);
167
168 // register log instance
169 serv->Register("/", log);
170
171 // while server runs in read-only mode, we should allow methods execution
172 serv->Restrict("/log", "allow_method=Select,GetTitle");
173
174 // register exit command
175 serv->RegisterCommand("/Stop","bRun=kFALSE;", "rootsys/icons/ed_delete.png");
176 serv->RegisterCommand("/ExitRoot","gSystem->Exit(1);", "rootsys/icons/ed_delete.png");
177
178 // Fill histograms randomly
179 TRandom3 random;
180 Float_t px, py;
181 const Long_t kUPDATE = 1000;
182 Long_t cnt = 0;
183 while (bRun) {
184 random.Rannor(px,py);
185 hpx->Fill(px);
186 hpxpy->Fill(px,py);
187
188 // IMPORTANT: one should regularly call ProcessEvents
189 if (cnt++ % kUPDATE == 0) {
190 if (gSystem->ProcessEvents()) break;
191
192 Long_t loop = cnt / kUPDATE;
193
194 // make messages not very often
195 if (loop % 1000 == 0) {
196 loop = loop/1000;
197 int shift = loop % 40;
198 // make a 'stairs' with spaces
199 log->AddMsg(TString::Format("%*s Message %ld", shift, "", loop));
200 }
201 }
202 }
203
204 delete serv; // delete http server
205}
void Class()
Definition: Class.C:29
int Int_t
Definition: RtypesCore.h:43
long Long_t
Definition: RtypesCore.h:52
bool Bool_t
Definition: RtypesCore.h:61
long long Long64_t
Definition: RtypesCore.h:71
float Float_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define ClassDef(name, id)
Definition: Rtypes.h:322
char name[80]
Definition: TGX11.cxx:109
double log(double)
R__EXTERN TSystem * gSystem
Definition: TSystem.h:556
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:37
UInt_t Get() const
Return raw date/time as encoded by TDatime.
Definition: TDatime.cxx:239
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
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:8393
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3275
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:294
Bool_t Register(const char *subfolder, TObject *obj)
Register object in subfolder.
TRootSniffer * GetSniffer() const
returns pointer on objects sniffer
Definition: THttpServer.h:81
Bool_t RegisterCommand(const char *cmdname, const char *method, const char *icon=0)
Register command which can be executed from web interface.
void Restrict(const char *path, const char *options)
Restrict access to specified object.
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:99
virtual void RemoveLast()
Remove the last object of the list.
Definition: TList.cxx:908
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:692
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:401
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
Collectable string class.
Definition: TObjString.h:28
void SetString(const char *s)
Definition: TObjString.h:45
Mother of all ROOT objects.
Definition: TObject.h:37
Random number generator class based on M.
Definition: TRandom3.h:27
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
void SetAutoLoad(const char *scripts="")
When specified, _autoload attribute will be always add to top element of h.json/h....
virtual Int_t GetLast() const
Returns index of last object in collection.
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
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
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:1291
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:414
const char * cnt
Definition: TXMLSetup.cxx:74