Http request response time monitoring
Tags: monitoring, beginners, programming, tutorial
Published: 2024-01-16 17:36:05

<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Hi developers!</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Today I would like to address a subject that has given me a hard time. I am sure this must have been the case for quite a number of you already (so-called “the bottleneck”). Since this is a broad topic, this article will only focus on identifying incoming HTTP requests that could be causing slowness issues. I will also provide you with a small tool I have developed to help identify them.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Our software is becoming more and more complex, processing a large number of requests from different sources, be it front-end or third-party back-end applications. To ensure optimal performance, it is essential to have a logging system capable of taking a few key measurements, such as the response time, the number of global references and the number of lines of code executed for each HTTP response. As part of my work, I get involved in the development of EMR software as well as incident analysis.&nbsp; Since user load comes mostly from HTTP requests (REST API or CSP application), the need to have this type of measurement when generalized slowness issues occur has become obvious.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><!--break--><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:700"><span style="font-style:normal"><span style="text-decoration:none">Response time measurement</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">One of the most relevant elements to evaluate the performance of an application is the response time. Each request must be answered within a reasonable time to provide a satisfactory user experience. This is why by recording the response time for each request, a logging system helps us identify bad performance. We can also use this information to pinpoint which APIs or CSPs are slower than others in order to optimize them and thus increase the overall execution of the application.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:700"><span style="font-style:normal"><span style="text-decoration:none">The global reference number</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Although the response time is a critical characteristic, we should not neglect the number of global references either. We should remember that disk access is often an expensive operation in terms of execution time too. The efficiency of the IRIS cache can mask this problem though. What I mean by that is that if many global cached references are accessed simultaneously, the response time is outstanding. Still, the performance drops considerably as soon as the data we access comes from outside the cache. In other words, in a system where multiple requests are made concurrently, excessive use of disk access can cause significant slowdowns. A log system that measures global access references for each request</span></span></span></span></span></span><span style="color:#000000;"> makes it also possible for us to detect </span><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">HTTP requests that excessively solicit resources. By identifying such issues, developers can make changes to minimize this access (by adding indexes, optimizing SQL queries, changing the logic, etc.)</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:700"><span style="font-style:normal"><span style="text-decoration:none">Number of lines of code executed</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Counting the number of lines of code executed for each request provides us with a measure of the complexity and magnitude of the operations performed. This metric helps us identify queries that run too many lines of code, which may indicate pieces of the code that require optimization. In most cases, the problem lies in the number of global references. However, in the event of a complex part of code being only the manipulation of memory data with little access to the database, this measurement will make it possible to highlight it (for example, if there is a problem with loops).</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:700"><span style="font-style:normal"><span style="text-decoration:none">Anomaly detection</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">A system log can also be used to detect anomalies in response query performance. By recording these measurements, you can identify requests that are out of the ordinary. For instance, if a query that typically runs fast suddenly starts taking longer or accessing the disk excessively, this may mean that there is a potential problem that requires immediate attention (e.g. increased response time after an application update). Keep in mind that early anomaly detection helps us quickly resolve performance issues and ensures a good user experience.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:700"><span style="font-style:normal"><span style="text-decoration:none">Package web-timing-logger</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Recently, I have developed a small tool for the community that allows us to log all incoming HTTP requests. It is available on Open Exchange if you got interested in it. This tool notably records the key metrics discussed in this article: number of lines of code executed, number of global referrals, and response time. It also logs some information about the caller that can come in handy for debugging:</span></span></span></span></span></span></p>

<ul>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Date and time.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">The user logged in.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Caller's IP address.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">URL.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Execution namespace.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Application web.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Page name (if applicable).</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">URL without parameters.</span></span></span></span></span></span></li>
</ul>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2o19s4uzzgf7j5svtd4x.png) 
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">In addition to that, it also offers the ability to integrate custom metrics with SAM (“/api/monitor”), which can allow you to incorporate them i</span></span></span></span></span></span><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">nto Prom</span></span></span></span></span></span><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">etheus and make a dashboard with Grafana.</span></span></span></span></span></span><br><br><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">There is a series of data per web application, page, or route (if it’s a REST application) ​​aggregated per day as well as per quarter-hour:</span></span></span></span></span></span></p>

<ul>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Total hit: Number of requests received.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Total timing: cumulative response time for all requests.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Max timing: slowest response time.</span></span></span></span></span></span></li>
<li aria-level="1" style="list-style-type:disc"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Average timing: average response time.</span></span></span></span></span></span></li>
</ul>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">The same metrics are available as well for global references and lines of code executed.</span></span></span></span></span></span></p>
<p style="line-height: 1.38;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
<span>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><img alt="Fichier:Prometheus software logo.svg — Wikipédia" src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Prometheus_software_logo.svg/2066px-Prometheus_software_logo.svg.png" style="height: 149px; width: 150px;"></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Below you can see an example with the metrics enabled on the web applications “</span></span></span></span></span></span><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:'Courier New',monospace"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">/api/monitor/”</span></span></span></span></span></span><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none"> and “</span></span></span></span></span></span><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:'Courier New',monospace"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">/csp/sys/exp/”</span></span></span></span></span></span><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos">webmeasure_average_gloref{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">903.5227272727272727</span>
webmeasure_average_gloref{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">903.5227272727272727</span>
webmeasure_average_gloref{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">1853.6875</span>
webmeasure_average_gloref{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">1242.933333333333333</span>
webmeasure_average_gloref{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">11015</span>
webmeasure_average_gloref_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">903.5227272727272727</span>
webmeasure_average_gloref_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">903.5227272727272727</span>
webmeasure_average_gloref_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">1853.6875</span>
webmeasure_average_gloref_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">1242.933333333333333</span>
webmeasure_average_gloref_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">11015</span>
webmeasure_average_lines{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">29365.5</span>
webmeasure_average_lines{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">29365.5</span>
webmeasure_average_lines{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">19415.5</span>
webmeasure_average_lines{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">11570.73333333333333</span>
webmeasure_average_lines{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">137087</span>
webmeasure_average_lines_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">29365.5</span>
webmeasure_average_lines_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">29365.5</span>
webmeasure_average_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">19415.5</span>
webmeasure_average_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">11570.73333333333333</span>
webmeasure_average_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">137087</span>
webmeasure_average_timing_in_ms{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">27.27256818181818182</span>
webmeasure_average_timing_in_ms{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">27.27256818181818182</span>
webmeasure_average_timing_in_ms{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">16.6</span>
webmeasure_average_timing_in_ms{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">9.94633333333333333</span>
webmeasure_average_timing_in_ms{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">116.405</span>
webmeasure_average_timing_in_ms_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">27.27256818181818182</span>
webmeasure_average_timing_in_ms_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">27.27256818181818182</span>
webmeasure_average_timing_in_ms_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">16.6</span>
webmeasure_average_timing_in_ms_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">9.94633333333333333</span>
webmeasure_average_timing_in_ms_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">116.405</span>
webmeasure_max_lines{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">29498</span>
webmeasure_max_lines{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">29498</span>
webmeasure_max_lines{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">137087</span>
webmeasure_max_lines{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">45208</span>
webmeasure_max_lines{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">137087</span>
webmeasure_max_lines_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">29498</span>
webmeasure_max_lines_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">29498</span>
webmeasure_max_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">137087</span>
webmeasure_max_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">45208</span>
webmeasure_max_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">137087</span>
webmeasure_max_timing{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">40.783</span>
webmeasure_max_timing{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">40.783</span>
webmeasure_max_timing{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">116.405</span>
webmeasure_max_timing{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">66.458</span>
webmeasure_max_timing{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">116.405</span>
webmeasure_max_timing_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">40.783</span>
webmeasure_max_timing_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">40.783</span>
webmeasure_max_timing_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">116.405</span>
webmeasure_max_timing_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">66.458</span>
webmeasure_max_timing_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">116.405</span>
webmeasure_total_gloref{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">39755</span>
webmeasure_total_gloref{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">39755</span>
webmeasure_total_gloref{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">29659</span>
webmeasure_total_gloref{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">18644</span>
webmeasure_total_gloref{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">11015</span>
webmeasure_total_gloref_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">39755</span>
webmeasure_total_gloref_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">39755</span>
webmeasure_total_gloref_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">29659</span>
webmeasure_total_gloref_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">18644</span>
webmeasure_total_gloref_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">11015</span>
webmeasure_total_hit{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">44</span>
webmeasure_total_hit{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">44</span>
webmeasure_total_hit{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">16</span>
webmeasure_total_hit{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">15</span>
webmeasure_total_hit{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">1</span>
webmeasure_total_hit_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">44</span>
webmeasure_total_hit_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">44</span>
webmeasure_total_hit_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">16</span>
webmeasure_total_hit_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">15</span>
webmeasure_total_hit_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">1</span>
webmeasure_total_lines{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">1292082</span>
webmeasure_total_lines{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">1292082</span>
webmeasure_total_lines{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">310648</span>
webmeasure_total_lines{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">173561</span>
webmeasure_total_lines{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">137087</span>
webmeasure_total_lines_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">1292082</span>
webmeasure_total_lines_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">1292082</span>
webmeasure_total_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">310648</span>
webmeasure_total_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">173561</span>
webmeasure_total_lines_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">137087</span>
webmeasure_total_timing_in_ms{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">1199.993</span>
webmeasure_total_timing_in_ms{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">1199.993</span>
webmeasure_total_timing_in_ms{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">265.6</span>
webmeasure_total_timing_in_ms{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">149.195</span>
webmeasure_total_timing_in_ms{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">116.405</span>
webmeasure_total_timing_in_ms_current_quarter{id=<span class="hljs-string">"/api/monitor/"</span>} <span class="hljs-number">1199.993</span>
webmeasure_total_timing_in_ms_current_quarter{id=<span class="hljs-string">"/api/monitor/metrics"</span>} <span class="hljs-number">1199.993</span>
webmeasure_total_timing_in_ms_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/"</span>} <span class="hljs-number">265.6</span>
webmeasure_total_timing_in_ms_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.Broker.cls"</span>} <span class="hljs-number">149.195</span>
webmeasure_total_timing_in_ms_current_quarter{id=<span class="hljs-string">"/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"</span>} <span class="hljs-number">116.405</span></code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">You could have noticed that the metrics illustrated above are very generic. I strongly encourage you to expand your metrics and make them personalized. It is necessary for proper monitoring of your applications.</span></span></span></span></span></span></p>

<p>&nbsp;</p>
<p><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:700"><span style="font-style:normal"><span style="text-decoration:none">Installation using ZPM</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">If you want to do a test install, and you are a Docker user, I recommend that you review this section for some practical information and move on to the next one. The container build is scripted to configure the environment automatically.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">The installation is done with ZPM. Simple go to the IRIS terminal and do the following:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos">zpm <span class="hljs-string">"install web-timing-logger”</span></code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Once installed, you need to initialize the settings, so just run:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(dc.webtiming.Config).Initialize()</code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">By default, the HTTP request log and metrics are not active. To enable them, take the following steps:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(dc.webtiming.Config).SetLogEnabled(<span class="hljs-number">1</span>)

<span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(dc.webtiming.Config).SetMetricsEnabled(<span class="hljs-number">1</span>)</code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">In order for SAM (“/api/monitor”) to expose custom metrics, not only must you add a role to the web application /API/monitor, but also register a class in SYS.Monitor.SAM.Config, so run the following command:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(dc.webtiming.Config).ConfigureAPIMonitor()</code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">If you want to use this utility in several web applications that run in different namespaces, it is crucial to map the package “dc.webtiming" as well as the globals "dc.webtiming*” in “%ALL”.&nbsp; To avoid doing it manually, use the method specified below:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(dc.webtiming.Config).AddToPercentAllNS()</code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">All of the abovementioned actions can be performed in a single line with the next command:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(dc.webtiming.Config).DefaultSetup()</code></pre>
<p><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:700"><span style="font-style:normal"><span style="text-decoration:none">Installation using Docker</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">The beginning with Docker is classic. Clone the repository and start the container:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="12" lang="Shell Session" tabsize="4"><code class="language-shell hljs">git clone https://github.com/lscalese/iris-web-timing-logger.git
docker-compose up -d</code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:700"><span style="font-style:normal"><span style="text-decoration:none">Activation on a web application</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Now that we have configured the system, there is still one important detail to be settled to enable you to record the measurements. To understand what you need to do, you should know how the system works.&nbsp; To trigger measurement and recording, web-timing-logger uses events "OnStartRequest" and "OnEndRequest". These events are implemented in the class "dc.webtiming.CSPSessionEvents", which is a subclass of "%CSP.SessionEvents". Thus, each web application must be configured with the event class "dc.webtiming.CSPSessionEvents".</span></span></span></span></span></span></p>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gsbfjtmizvusew3q6ebn.png) 

<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">If your web application is already using another event class, don't worry! Just add the following calls to this class:</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">In the methodOnStartRequest:&nbsp;</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(dc.webtiming.Events).OnStart()</code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">and in the method OnEndRequest:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Do</span> <span class="hljs-keyword">##class</span>(dc.webtiming.Events).OnEnd()</code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">This will add measurement and recording functionality to your existing event class.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Perform this configuration for all web applications you want to measure.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">In the case, you have an empty system and only want to do some tests, use the configuration on the /API/monitor application. Since access to metrics is established via an HTTP call, they can also be measured to generate logs.&nbsp; So just open your browser and access the page http://localhost:49165/api/monitor/metrics several times (adapt it with your port number). You will notice that the metrics “webmeasure” are powered, and the table “dc_webtiming_log.Request“ is filled with data from HTTP requests:</span></span></span></span></span></span></p>

<pre class="codeblock-container" idlang="1" lang="SQL" tabsize="4"><code class="language-sql hljs"><span class="hljs-keyword">SELECT</span> *
<span class="hljs-keyword">FROM</span> dc_webtiming_log.Request</code></pre>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Even though Web-timing-logger makes it easy to identify problematic entry points in web applications, it does not provide precise information on the specific parts of the code that are causing troubles. &nbsp; Once the entry point has been identified, you can use other tools, such as <a href="https://openexchange.intersystems.com/package/ZProfile" target="_blank">OEX ZProfile</a>, developed by Dmitry Maslennikov. It can perform an in-depth analysis of the code that is being executed. Check out a dedicated </span></span></span></span></span></span><a href="https://community.intersystems.com/post/profile-objectscript-more-power" style="text-decoration:none"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#1155cc"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:underline"><span style="-webkit-text-decoration-skip:none"><span style="text-decoration-skip-ink:none">article here</span></span></span></span></span></span></span></span></a><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">Well, that's all for today. There are, of course, other things that we could address on “web-timing-logger”, such as cleaning logs, Grafana dashboard example, or even some interesting SQL queries. I hope you enjoyed the article will give you ideas for monitoring your applications. I might write a sequel if you are interested in it.</span></span></span></span></span></span></p>
<p style="line-height:1.38"><span style="font-size:11pt; font-variant:normal; white-space:pre-wrap"><span style="font-family:Arial,sans-serif"><span style="color:#000000"><span style="font-weight:400"><span style="font-style:normal"><span style="text-decoration:none">See you soon!</span></span></span></span></span></span></p>