NCBI C++ ToolKit
ncbi_usage_report_api_sample.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_usage_report_api_sample.cpp 102403 2024-05-01 13:52:13Z ivanov $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Vladimir Ivanov
27  *
28  * File Description:
29  * CUsageReport API samples for logging usage information.
30  *
31  * This example is working, but don't log anything to the Applog,
32  * we set wrong dummy reporting URL, redefining real one for the sample purposes.
33  * So, all reports here will fail actually.
34  *
35  * Also, see ncbi_usage_report_sample.ini in the same directory for allowed
36  * configuration options, or check CUsageReportAPI class, that have
37  * corresponding options.
38  *
39  */
40 
41 #include <ncbi_pch.hpp>
42 #include <corelib/ncbiapp.hpp>
44 
46 
47 
48 /////////////////////////////////////////////////////////////////////////////
49 // Sample NCBI application
50 
52 {
53 public:
55  void Init();
56  int Run();
57 
58  /// Global API configuration example
59  void ConfigureAPI();
60 
61  // Below are examples of 3 different usage patterns,
62  // all can be used separately or in conjunction with each other.
63 
64  /// Simplest way to report -- use provided macro
65  void Pattern_1_SimpleMacro();
66  /// Custom reporters
68  /// Advanced reporting method with custom jobs and reporting status control
70 };
71 
72 
74 {
75  // If application have version, it will be automatically reported
76  // alongside with host, OS name and application name.
77  //
78  NCBI_APP_SET_VERSION(1, 2, 3); // Extended variant of SetVersion(CVersionInfo(1,2,3));
79 }
80 
81 
83 {
84  // Some application initialization ("Warning" for test purposes only)
86 }
87 
88 
90 {
91  // API configuration example
92  ConfigureAPI();
93 
94  // Usage pattern
98 
99  // Global reporter:
100  // Wait until all requests are reported. Optional.
102  //NCBI_REPORT_USAGE_WAIT_ALWAYS;
103  //NCBI_REPORT_USAGE_WAIT_IF_SUCCESS;
104  //NCBI_REPORT_USAGE_WAIT_TIMEOUT(CTimeout(5,0));
105 
106  // Gracefully terminate reporting API. Optional.
108 
109  return 0;
110 }
111 
112 
114 {
115  // Global API configuration.
116  //
117  // Each call here is optional.
118  // Any parameter can be set via configuration file or environment variable.
119 
120  // Set application name and version.
121  // New values will NOT redefine application name and version, if specified,
122  // see CUsageReportSampleApp constructor and Init().
123  // But these calls can be used for any non-CNcbiApplication-based applications.
124  //
125  // So, all 3 calls above doesn't have any effect in our case.
126  //
127  CUsageReportAPI::SetAppName("usage_report_sample");
129  // or set version as string
131 
132 
133  // Set what should be reported by default with any report
134  // If default parameters didn't changed, the OS name will be reported by default too.
138 
139 
140  // Set non-standard global URL for reporting
141  // Think twice why you need to change default URL.
143  CUsageReportAPI::SetURL("http://dummy/cgi");
145 
146  // Change timeout and/or number of retries if necessary (optional)
147  // We will use 1 sec timeout in this sample, and no retries on error
150 
151  // Change queue size for storing jobs reported in background, if needed.
153 
154  // And finally enable reporting API (global flag). It is disabled by default.
156 }
157 
158 
160 {
161  // Simplest way to report -- use provided macro.
162  // All macro use global API reporter and can be used from any thread, MT safe.
163  // No any control over reporting or checking status.
164 
165  // Enable reporting.
166  // Can be enabled/disabled via configuration file or environment variable.
167  // Same as CUsageReportAPI::Enable() above -- we already enabled API there.
169 
170  // First parameter automatically sets to "jsevent=eventname".
171  // Below are some reports with variable number of parameters.
172  // All default parameters like application name, version and etc
173  // will be automatically added during sending data to server.
174  //
175  NCBI_REPORT_USAGE("eventname");
176  NCBI_REPORT_USAGE("eventname", .Add("tool_name", "ABC"));
177  NCBI_REPORT_USAGE("eventname", .Add("tool_name", "DEF").Add("tool_version", 1));
178  NCBI_REPORT_USAGE("eventname",
179  .Add("tool_name", "XYZ")
180  .Add("tool_version", 2)
181  .Add("one_more_parameter", 123.45));
182 
183  // Next 2 call are optional. Add them to be sure that all was sent befor an application exit.
184 
185  // Wait until all requests are reported.
186  //NCBI_REPORT_USAGE_WAIT;
187  //NCBI_REPORT_USAGE_WAIT_ALWAYS;
188  //NCBI_REPORT_USAGE_WAIT_IF_SUCCESS;
189 
190  // Gracefully terminate global reporting API.
191  // Commented because we will use global reporter again below.
192  //NCBI_REPORT_USAGE_FINISH;
193 }
194 
195 
197 {
198  // Custom local reporters.
199  //
200  // We still recommend do use single global reporter,
201  // but if you want to report to different URLs at the same time you may
202  // construct your own reporter. Newly created reporters inherit all
203  // configuration parameters from CUsageReportAPI.
204 
205  // First reporter will not use any default reporting parameters
206  CUsageReport reporter1(CUsageReport::fNone, "http://url_1");
207  // Second will report to another URL and report all defaults specified
208  // for CUsageReportAPI at the moment.
209  CUsageReport reporter2(CUsageReport::fDefault, "http://url_2");
210 
211  CUsageReportParameters params1, params2;
212 
213  // Report some parameters to both
214  params1.Add("p1", "v1");
215  reporter1.Send(params1);
216  params2.Add("p2", "v2");
217  reporter2.Send(params2);
218 
219  // Change parameter and report again to 1st only
220  params1.Add("p1", "new value for p1");
221  reporter1.Send(params1);
222 
223  // ...
224 
225  // Wait and finish. Better to call them once per reporter
226  // before finishing reporting and application exit, or when
227  // you don't need them anymore.
228 
229  reporter1.Wait(); reporter1.Finish();
230  reporter2.Wait(); reporter2.Finish();
231 }
232 
233 
235 {
236  // Advanced method with custom jobs and control for reporting process.
237 
238  /// Example of a simple custom reporting job
239  class CMyJob : public CUsageReportJob
240  {
241  public:
242  /// Our example will have some integer ID to distinguish jobs
243  CMyJob(int id = 0) : m_ID(id) {};
244 
245  /// Override OnStateChange() if want to control reporting status
246  virtual void OnStateChange(EState state)
247  {
248  string state_str;
249  switch (state) {
251  // Job has added to queue
252  state_str = "Queued";
253  break;
255  // Job extracted from queue and going to be send to server
256  state_str = "Running";
257  break;
259  // No error for reporting this job
260  break;
262  // Reporting failed, you can print error message for example
263  ERR_POST(Warning << "Reporting failed for job " << m_ID);
264  // Or disable future reporting for current reporter at all:
265  //CUsageReportAPI::Disable();
266  state_str = "Failed";
267  break;
269  // Reporting canceled for this job due CUsageReport:: ClearQueue() / Finish() / Disable()
270  state_str = "Canceled";
271  break;
273  // Too many requests, queue is full, job cannot be processed
274  state_str = "Rejected";
275  break;
276  default:
277  _TROUBLE;
278  }
279  cout << "callback: job " << m_ID << " -> " << state_str << endl << flush;
280  };
281 
282  /// Copy constructor.
283  /// For trivial classes like this it is not really necessary,
284  /// default copy constructor can be used. But if you have pointers
285  /// or any other data types that cannot be just copied, you need
286  /// to implement it.
287  ///
288  CMyJob(const CMyJob& other) : CUsageReportJob(other) {
289  // Copy members:
290  m_ID = other.m_ID;
291  };
292 
293  protected:
294  int m_ID; ///< some job ID for example
295  };
296 
297  // We will use global reporter here, but this can be applied to any reporter.
298  CUsageReport& reporter = CUsageReport::Instance();
299 
300  // Because we set dummy URL for our reporter, bigger half of jobs will fails,
301  // and remaining part rejected, because current queue size is 20 only.
302  // The reporter will unable to process all, we add jobs faster.
303  //
304  for (int i = 1; i < 40; i++) {
305  // Create custom job with ID equal to 'i'
306  CMyJob job(i);
307  // Add some extra parameters if necessary
308  job.Add("p1", i*2);
309  job.Add("p2", "v" + std::to_string(i));
310  // Send (add to asynchronous reporting queue)
311  reporter.Send(job);
312  }
313  // Waiting and finishing -- not yet, see Run()
314  // Usages:
315  // reporter.Wait();
316  // reporter.Wait(CUsageReport::eSkipIfNoConnection);
317  // reporter.Wait(CUsageReport::eAlways, CTimeout(5,0));
318  //reporter.Finish();
319 }
320 
321 
322 
323 /////////////////////////////////////////////////////////////////////////////
324 // MAIN
325 
326 int main(int argc, const char* argv[])
327 {
328  // Each application have a name. It can be specified as last parameter
329  // in arguments to AppMain, or extracted from the executable file name.
330  // So it can be automatically used for reporting.
331 
332  return CUsageReportSampleApp().AppMain(argc, argv, 0, eDS_Default, "", "SampleAppName");
333 }
CTimeout – Timeout interval.
Definition: ncbitime.hpp:1693
CUsageReportJob::
CUsageReportParameters::
void Pattern_2_MultipleReporters()
Custom reporters.
void ConfigureAPI()
Global API configuration example.
void Pattern_1_SimpleMacro()
Simplest way to report – use provided macro.
int Run()
Run the application.
void Pattern_3_StatusControl()
Advanced reporting method with custom jobs and reporting status control.
void Init()
Initialize the application.
CUsageReport::
CVersionInfo –.
int AppMain(int argc, const char *const *argv, const char *const *envp=0, EAppDiagStream diag=eDS_Default, const char *conf=NcbiEmptyCStr, const string &name=NcbiEmptyString)
Main function (entry point) for the NCBI application.
Definition: ncbiapp.cpp:819
EDiagSev SetDiagPostLevel(EDiagSev post_sev=eDiag_Error)
Set the threshold severity for posting the messages.
Definition: ncbidiag.cpp:6129
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
@ eDS_Default
Try standard log file (app.name + ".log") in /log/, use stderr on failure.
Definition: ncbidiag.hpp:1790
@ eDiag_Warning
Warning message.
Definition: ncbidiag.hpp:652
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
#define NCBI_REPORT_USAGE_START
Enable usage statistics reporting (globally for all reporters).
static void SetMaxQueueSize(unsigned n)
Declare the maximum reporting jobs queue size per reporter.
static void SetAppName(const string &name)
Set application name for the usage reporters.
static void SetTimeout(const CTimeout &timeout)
Set timeout for connection.
static void SetRetries(int retries)
Set muximum number of retries in case of error reporting.
void Finish(void)
Finish reporting for the current reporting object.
void Send(void)
Report usage statistics (asynchronously), default parameters.
#define NCBI_REPORT_USAGE(event,...)
Convenience macro to log "jsevent" usage statistics (asynchronously).
static void SetAppVersion(const string &version)
Set application version for the usage reporter(s).
#define NCBI_REPORT_USAGE_WAIT
Wait until all reports via NCBI_REPORT_USAGE will be processed.
static void SetDefaultParameters(TWhat what=fDefault)
Set default reporting parameters.
CUsageReportParameters & Add(const string &name, const string &value)
Add argument Name must contain only alphanumeric chars or '_'.
#define NCBI_REPORT_USAGE_FINISH
Finishing reporting via NCBI_REPORT_USAGE and global usage reporter,.
static CUsageReport & Instance(void)
Return global instance of CUsageReport.
static void SetEnabled(bool enable=true)
Enable or disable usage statistics reporting globally for all reporters.
static void SetURL(const string &url)
Change CGI URL for reporting usage statistics.
void Wait(EWait how=eAlways, CTimeout timeout=CTimeout(CTimeout::eDefault))
Wait until all queued jobs starts to process and queue is empty.
static bool CheckConnection()
Check that connection to reporting URL can be established.
@ fNone
No defaults, all parameters should be specified via CUsageReportParameters directly.
@ fAppVersion
Application version ("version")
@ fHost
Host name ("host")
@ fAppName
Application name ("appname")
@ eQueued
Added to queue (sending temporary postpones)
@ eFailed
Result: send failed.
@ eCanceled
Result: canceled / removed from queue.
@ eRejected
Result: rejected / too many requests.
@ eCompleted
Result: successfully sent.
@ eRunning
Ready to send.
int i
int main(int argc, const char *argv[])
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
#define NCBI_APP_SET_VERSION(major, minor, patch)
Definition: ncbiapp.hpp:60
#define _TROUBLE
#define _ASSERT
Modified on Thu May 02 14:29:26 2024 by modify_doxy.py rev. 669887