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