<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jhon Thomas Ticona Chambi</title>
    <description>The latest articles on DEV Community by Jhon Thomas Ticona Chambi (@jhonticonachambi).</description>
    <link>https://dev.to/jhonticonachambi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2987323%2F10a6b6f8-88a5-426d-bbb4-c2935896ab02.png</url>
      <title>DEV Community: Jhon Thomas Ticona Chambi</title>
      <link>https://dev.to/jhonticonachambi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jhonticonachambi"/>
    <language>en</language>
    <item>
      <title>Observability Practices: A Complete Guide with Node.js Implementation</title>
      <dc:creator>Jhon Thomas Ticona Chambi</dc:creator>
      <pubDate>Sat, 05 Jul 2025 04:33:47 +0000</pubDate>
      <link>https://dev.to/jhonticonachambi/observability-practices-a-complete-guide-with-nodejs-implementation-4bl3</link>
      <guid>https://dev.to/jhonticonachambi/observability-practices-a-complete-guide-with-nodejs-implementation-4bl3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's distributed systems landscape, &lt;strong&gt;observability&lt;/strong&gt; has become critical for understanding complex applications. This article demonstrates comprehensive observability practices using a real-world Node.js API integrated with &lt;strong&gt;Prometheus&lt;/strong&gt; and &lt;strong&gt;Grafana&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Pillars of Observability
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Metrics
&lt;/h3&gt;

&lt;p&gt;Numerical measurements providing quantitative insights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Business Metrics&lt;/strong&gt;: User registrations, transactions, revenue&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Metrics&lt;/strong&gt;: Response times, error rates, throughput&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Metrics&lt;/strong&gt;: CPU usage, memory consumption, disk I/O&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Logs
&lt;/h3&gt;

&lt;p&gt;Time-stamped records of discrete events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structured Logging&lt;/strong&gt;: JSON format for better parsing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual Information&lt;/strong&gt;: Request IDs, user context, transaction details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Different Log Levels&lt;/strong&gt;: DEBUG, INFO, WARN, ERROR, FATAL&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Traces
&lt;/h3&gt;

&lt;p&gt;Track requests across multiple services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Distributed Tracing&lt;/strong&gt;: Follow requests through microservices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Analysis&lt;/strong&gt;: Identify slow components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Mapping&lt;/strong&gt;: Understand service relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Implementation with Node.js
&lt;/h2&gt;

&lt;p&gt;Our demonstration project implements a RESTful API with comprehensive observability features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Overview
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js API (Port 3000) → Prometheus (Port 9090) → Grafana (Port 3000)
                ↓
    Traffic Generator (Test Script)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Core Metrics Implementation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  HTTP Request Duration Histogram
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpDuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;promClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Histogram&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http_request_duration_ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Duration of HTTP requests in ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;labelNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;buckets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Request Counter
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpRequests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;promClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http_requests_total&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Total HTTP requests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;labelNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Active Connections Gauge
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activeConnections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;promClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Gauge&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active_connections&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Active connections&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  API Endpoints for Testing
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /&lt;/code&gt;&lt;/strong&gt; - Basic health endpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /users&lt;/code&gt;&lt;/strong&gt; - List users with variable latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /users/:id&lt;/code&gt;&lt;/strong&gt; - Specific user lookup with error cases&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /slow&lt;/code&gt;&lt;/strong&gt; - Intentionally slow endpoint (2-5s response time)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /error&lt;/code&gt;&lt;/strong&gt; - Random error generation for testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /metrics&lt;/code&gt;&lt;/strong&gt; - Prometheus metrics endpoint&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Middleware Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Response time tracking&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;responseTime&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;httpDuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;httpRequests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;httpErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Essential Prometheus Queries
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Request Rate (RPS)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate(http_requests_total[1m])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Error Rate Percentage
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate(http_errors_total[1m]) / rate(http_requests_total[1m]) * 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  95th Percentile Response Time
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;histogram_quantile(0.95, rate(http_request_duration_ms_bucket[1m]))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Metric Design Principles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Standard Suffixes&lt;/strong&gt;: &lt;code&gt;_total&lt;/code&gt;, &lt;code&gt;_duration_seconds&lt;/code&gt;, &lt;code&gt;_bytes&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Labeling&lt;/strong&gt;: Standardize label names across services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid High Cardinality&lt;/strong&gt;: Limit unique label combinations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Golden Signals Implementation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Latency&lt;/strong&gt;: Time to process requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traffic&lt;/strong&gt;: Demand on your system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errors&lt;/strong&gt;: Rate of failed requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saturation&lt;/strong&gt;: Resource utilization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Effective Alerting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alert on Symptoms&lt;/strong&gt;: Focus on user impact, not causes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meaningful Thresholds&lt;/strong&gt;: Avoid alert fatigue&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runbook Integration&lt;/strong&gt;: Provide clear remediation steps&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitHub Repository
&lt;/h2&gt;

&lt;p&gt;The complete implementation with automated setup scripts is available:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/jhonticonachambi/observability-practices-nodejs.git" rel="noopener noreferrer"&gt;https://github.com/jhonticonachambi/observability-practices-nodejs.git&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Repository Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Complete source code with all implementation files&lt;/li&gt;
&lt;li&gt;✅ Automated setup scripts for Windows/Mac/Linux&lt;/li&gt;
&lt;li&gt;✅ Comprehensive documentation and troubleshooting guides&lt;/li&gt;
&lt;li&gt;✅ CI/CD ready with GitHub Actions integration&lt;/li&gt;
&lt;li&gt;✅ Traffic generator for realistic testing scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Observability transforms raw metrics into actionable insights that drive better system reliability and user experience. This implementation demonstrates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Holistic Approach&lt;/strong&gt;: Combining metrics, logs, and traces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practical Implementation&lt;/strong&gt;: Real-world Node.js example&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation First&lt;/strong&gt;: Scripted setup reduces barriers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Practices&lt;/strong&gt;: Following established patterns&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Next Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Extend metrics with business-specific measurements&lt;/li&gt;
&lt;li&gt;Implement meaningful alerting&lt;/li&gt;
&lt;li&gt;Add distributed tracing with Jaeger&lt;/li&gt;
&lt;li&gt;Apply patterns to production systems&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Jhon TiCona Chambi&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Technologies&lt;/strong&gt;: Node.js, Prometheus, Grafana, Express.js&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href="https://github.com/jhonticonachambi/observability-practices-nodejs.git" rel="noopener noreferrer"&gt;https://github.com/jhonticonachambi/observability-practices-nodejs.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>observability</category>
      <category>prometheus</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Observability Practices: A Complete Guide with Node.js Implementation</title>
      <dc:creator>Jhon Thomas Ticona Chambi</dc:creator>
      <pubDate>Sat, 05 Jul 2025 04:23:36 +0000</pubDate>
      <link>https://dev.to/jhonticonachambi/observability-practices-a-complete-guide-with-real-world-nodejs-implementation-fjc</link>
      <guid>https://dev.to/jhonticonachambi/observability-practices-a-complete-guide-with-real-world-nodejs-implementation-fjc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's distributed systems landscape, &lt;strong&gt;observability&lt;/strong&gt; has become critical for understanding complex applications. This article demonstrates comprehensive observability practices using a real-world Node.js API integrated with &lt;strong&gt;Prometheus&lt;/strong&gt; and &lt;strong&gt;Grafana&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Pillars of Observability
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Metrics
&lt;/h3&gt;

&lt;p&gt;Numerical measurements providing quantitative insights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Business Metrics&lt;/strong&gt;: User registrations, transactions, revenue&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Metrics&lt;/strong&gt;: Response times, error rates, throughput&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Metrics&lt;/strong&gt;: CPU usage, memory consumption, disk I/O&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Logs
&lt;/h3&gt;

&lt;p&gt;Time-stamped records of discrete events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structured Logging&lt;/strong&gt;: JSON format for better parsing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual Information&lt;/strong&gt;: Request IDs, user context, transaction details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Different Log Levels&lt;/strong&gt;: DEBUG, INFO, WARN, ERROR, FATAL&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Traces
&lt;/h3&gt;

&lt;p&gt;Track requests across multiple services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Distributed Tracing&lt;/strong&gt;: Follow requests through microservices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Analysis&lt;/strong&gt;: Identify slow components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Mapping&lt;/strong&gt;: Understand service relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Implementation with Node.js
&lt;/h2&gt;

&lt;p&gt;Our demonstration project implements a RESTful API with comprehensive observability features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Overview
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js API (Port 3000) → Prometheus (Port 9090) → Grafana (Port 3000)
                ↓
    Traffic Generator (Test Script)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Core Metrics Implementation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  HTTP Request Duration Histogram
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpDuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;promClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Histogram&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http_request_duration_ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Duration of HTTP requests in ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;labelNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;buckets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Request Counter
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpRequests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;promClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http_requests_total&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Total HTTP requests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;labelNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;method&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Active Connections Gauge
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activeConnections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;promClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Gauge&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active_connections&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Active connections&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  API Endpoints for Testing
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /&lt;/code&gt;&lt;/strong&gt; - Basic health endpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /users&lt;/code&gt;&lt;/strong&gt; - List users with variable latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /users/:id&lt;/code&gt;&lt;/strong&gt; - Specific user lookup with error cases&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /slow&lt;/code&gt;&lt;/strong&gt; - Intentionally slow endpoint (2-5s response time)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /error&lt;/code&gt;&lt;/strong&gt; - Random error generation for testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET /metrics&lt;/code&gt;&lt;/strong&gt; - Prometheus metrics endpoint&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Middleware Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Response time tracking&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;responseTime&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;httpDuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;httpRequests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;httpErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Essential Prometheus Queries
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Request Rate (RPS)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate(http_requests_total[1m])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Error Rate Percentage
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rate(http_errors_total[1m]) / rate(http_requests_total[1m]) * 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  95th Percentile Response Time
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;histogram_quantile(0.95, rate(http_request_duration_ms_bucket[1m]))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Metric Design Principles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Standard Suffixes&lt;/strong&gt;: &lt;code&gt;_total&lt;/code&gt;, &lt;code&gt;_duration_seconds&lt;/code&gt;, &lt;code&gt;_bytes&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Labeling&lt;/strong&gt;: Standardize label names across services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid High Cardinality&lt;/strong&gt;: Limit unique label combinations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Golden Signals Implementation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Latency&lt;/strong&gt;: Time to process requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traffic&lt;/strong&gt;: Demand on your system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errors&lt;/strong&gt;: Rate of failed requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saturation&lt;/strong&gt;: Resource utilization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Effective Alerting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alert on Symptoms&lt;/strong&gt;: Focus on user impact, not causes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meaningful Thresholds&lt;/strong&gt;: Avoid alert fatigue&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runbook Integration&lt;/strong&gt;: Provide clear remediation steps&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitHub Repository
&lt;/h2&gt;

&lt;p&gt;The complete implementation with automated setup scripts is available:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/jhonticonachambi/observability-practices-nodejs.git" rel="noopener noreferrer"&gt;https://github.com/jhonticonachambi/observability-practices-nodejs.git&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Repository Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Complete source code with all implementation files&lt;/li&gt;
&lt;li&gt;✅ Automated setup scripts for Windows/Mac/Linux&lt;/li&gt;
&lt;li&gt;✅ Comprehensive documentation and troubleshooting guides&lt;/li&gt;
&lt;li&gt;✅ CI/CD ready with GitHub Actions integration&lt;/li&gt;
&lt;li&gt;✅ Traffic generator for realistic testing scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Observability transforms raw metrics into actionable insights that drive better system reliability and user experience. This implementation demonstrates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Holistic Approach&lt;/strong&gt;: Combining metrics, logs, and traces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practical Implementation&lt;/strong&gt;: Real-world Node.js example&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation First&lt;/strong&gt;: Scripted setup reduces barriers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Practices&lt;/strong&gt;: Following established patterns&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Next Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Extend metrics with business-specific measurements&lt;/li&gt;
&lt;li&gt;Implement meaningful alerting&lt;/li&gt;
&lt;li&gt;Add distributed tracing with Jaeger&lt;/li&gt;
&lt;li&gt;Apply patterns to production systems&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Jhon TiCona Chambi&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Technologies&lt;/strong&gt;: Node.js, Prometheus, Grafana, Express.js&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href="https://github.com/jhonticonachambi/observability-practices-nodejs.git" rel="noopener noreferrer"&gt;https://github.com/jhonticonachambi/observability-practices-nodejs.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>observability</category>
      <category>prometheus</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Software Design Principles: Practical Implementation with User Roles</title>
      <dc:creator>Jhon Thomas Ticona Chambi</dc:creator>
      <pubDate>Fri, 28 Mar 2025 22:38:27 +0000</pubDate>
      <link>https://dev.to/jhonticonachambi/software-design-principles-practical-implementation-with-user-roles-45c5</link>
      <guid>https://dev.to/jhonticonachambi/software-design-principles-practical-implementation-with-user-roles-45c5</guid>
      <description>&lt;h2&gt;
  
  
  I. Introduction
&lt;/h2&gt;

&lt;p&gt;Software design is a fundamental pillar for developing scalable, maintainable, and flexible applications. To achieve this, we use the SOLID principles, a set of best practices in object-oriented programming.  &lt;/p&gt;

&lt;p&gt;In this document, we focus on two specific SOLID principles:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Liskov Substitution Principle (LSP)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface Segregation Principle (ISP)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Through a practical implementation based on user roles, we will see how these principles improve the structure and maintainability of the code.  &lt;/p&gt;




&lt;h2&gt;
  
  
  II. SOLID Principles
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;SOLID&lt;/strong&gt; acronym represents five key principles in object-oriented programming:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt; - &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;: A class should have a single responsibility.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O&lt;/strong&gt; - &lt;strong&gt;Open/Closed Principle (OCP)&lt;/strong&gt;: Code should be open for extension but closed for modification.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L&lt;/strong&gt; - &lt;strong&gt;Liskov Substitution Principle (LSP)&lt;/strong&gt;: Subclasses should be able to replace their base class without altering functionality.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt; - &lt;strong&gt;Interface Segregation Principle (ISP)&lt;/strong&gt;: Interfaces should be specific rather than general.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt; - &lt;strong&gt;Dependency Inversion Principle (DIP)&lt;/strong&gt;: High-level modules should not depend on low-level modules but on abstractions.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this project, we apply &lt;strong&gt;LSP&lt;/strong&gt; and &lt;strong&gt;ISP&lt;/strong&gt; to design a well-structured user role system.  &lt;/p&gt;




&lt;h2&gt;
  
  
  III. Implementing LSP and ISP in a User Role System
&lt;/h2&gt;

&lt;p&gt;In a system where users have different roles (Reader, Editor, Administrator), applying &lt;strong&gt;LSP&lt;/strong&gt; and &lt;strong&gt;ISP&lt;/strong&gt; is key to ensuring flexibility and maintainability.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;A. Applying Liskov Substitution Principle (LSP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Liskov Substitution Principle&lt;/strong&gt; states that a subclass should be able to replace its base class without affecting expected behavior.  &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;How we apply it in our implementation:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;We create a base class &lt;code&gt;User&lt;/code&gt; with common attributes (name and email).
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Reader&lt;/code&gt;, &lt;code&gt;Editor&lt;/code&gt;, and &lt;code&gt;Admin&lt;/code&gt; classes inherit from &lt;code&gt;User&lt;/code&gt;, making them interchangeable in the code.
&lt;/li&gt;
&lt;li&gt;Each subclass implements only the necessary functionalities without modifying base behavior.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that we can substitute a &lt;code&gt;User&lt;/code&gt; with any subclass (&lt;code&gt;Reader&lt;/code&gt;, &lt;code&gt;Editor&lt;/code&gt;, &lt;code&gt;Admin&lt;/code&gt;) without affecting the overall functionality of the system.  &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;B. Applying Interface Segregation Principle (ISP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Interface Segregation Principle&lt;/strong&gt; states that it's preferable to have several specific interfaces rather than a single general one with many responsibilities.  &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;How we apply it in our implementation:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Instead of a single general interface for all users, we create separate interfaces:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;IReader&lt;/code&gt;: For users with reading permissions.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IEditor&lt;/code&gt;: For users with editing permissions.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IAdmin&lt;/code&gt;: For users with administrative permissions.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Each class implements only the interfaces it needs, avoiding unnecessary methods.
&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This reduces unnecessary dependencies and improves system scalability.  &lt;/p&gt;




&lt;h2&gt;
  
  
  IV. Implementation Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;

&lt;span class="c1"&gt;# Specific Interfaces (ISP)
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;edit_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IAdmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;delete_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Base Class (LSP)
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IUser&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;

&lt;span class="c1"&gt;# Subclasses applying LSP and ISP
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IReader&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is reading.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Editor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEditor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;edit_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; has edited content.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Admin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Editor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IAdmin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;delete_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; has deleted content.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  V. Conclusion
&lt;/h2&gt;

&lt;p&gt;By applying &lt;strong&gt;Liskov Substitution Principle (LSP)&lt;/strong&gt; and &lt;strong&gt;Interface Segregation Principle (ISP)&lt;/strong&gt;, we have built a more flexible, scalable, and maintainable user role system.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LSP ensures&lt;/strong&gt; that subclasses can replace their base class without altering the system’s expected behavior.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ISP ensures&lt;/strong&gt; that classes implement only the necessary interfaces, avoiding bloated and unnecessary dependencies.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These principles contribute to clean code, facilitating future modifications and reducing complexity in large-scale applications.  &lt;/p&gt;

&lt;p&gt;For more details and source code, visit the GitHub repository: &lt;a href="https://github.com/jhonticonachambi/solid-roles.git" rel="noopener noreferrer"&gt;SOLID User Roles&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>solidprinciples</category>
    </item>
  </channel>
</rss>
