<?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: Hussein El-Hewehi</title>
    <description>The latest articles on DEV Community by Hussein El-Hewehi (@husseinhewehii).</description>
    <link>https://dev.to/husseinhewehii</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%2F2967889%2Fcda0c3a1-685b-4e7d-8ffd-249ed73d78b3.jpeg</url>
      <title>DEV Community: Hussein El-Hewehi</title>
      <link>https://dev.to/husseinhewehii</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/husseinhewehii"/>
    <language>en</language>
    <item>
      <title>Dear Loved Ones, Relax—AI Will Not Take Your Jobs! 🤖✨</title>
      <dc:creator>Hussein El-Hewehi</dc:creator>
      <pubDate>Sat, 29 Mar 2025 05:22:23 +0000</pubDate>
      <link>https://dev.to/husseinhewehii/dear-loved-ones-relax-ai-will-not-take-your-jobs-22bf</link>
      <guid>https://dev.to/husseinhewehii/dear-loved-ones-relax-ai-will-not-take-your-jobs-22bf</guid>
      <description>&lt;p&gt;This is a submission for the &lt;a href="https://future.forem.com/challenges/writing-2025-02-26"&gt;Future Writing Challenge&lt;/a&gt;: How Technology Is Changing Things&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dear Loved ones,&lt;/strong&gt;&lt;br&gt;
The fear of AI replacing human jobs is nothing new. It mirrors past revolutions—just as industrial machines once terrified &lt;strong&gt;peasants&lt;/strong&gt;, &lt;strong&gt;craftsmen&lt;/strong&gt; &amp;amp; &lt;strong&gt;factory workers&lt;/strong&gt;, today’s workers worry that AI will make them obsolete. But history tells a different story! 📖⏳&lt;/p&gt;

&lt;h2&gt;
  
  
  I am a "History Repeats Itself 🔄" advocate
&lt;/h2&gt;

&lt;p&gt;When the Industrial Revolution began, many feared machines would replace them 🏗️, causing job losses. And they did—but they also created entirely new industries and opportunities! AI is simply the next chapter 📜 of this evolution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jobs Will Change, Not Disappear 💡
&lt;/h2&gt;

&lt;p&gt;AI will automate repetitive tasks 🤖🔄, but that doesn’t mean mass unemployment. Instead, it will shift human work toward creativity 🎨, problem-solving 🧠, and new fields we haven’t even imagined yet! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  More Jobs, Not Fewer 📈
&lt;/h2&gt;

&lt;p&gt;Just as past revolutions led to a surge in new professions, AI will generate demand for (AI-User) workers, &lt;strong&gt;not to mention&lt;/strong&gt; the engineers who will train the AI 🛠️, and countless other roles that don’t yet exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Adapt and Thrive 🌱
&lt;/h2&gt;

&lt;p&gt;Humans have always adapted to technological progress. The key is not to fear AI, but to embrace and learn from it. Those who upskill 📚 and evolve with technology will find more opportunities, not fewer! 🌍💼&lt;/p&gt;

&lt;p&gt;So, let’s not panic—let’s prepare! 🔥💪 AI isn’t here to take everything from us—it’s here to push us forward, just as every great innovation has before! 🌟🚀&lt;/p&gt;

&lt;p&gt;Sincerely,&lt;br&gt;
Hussein ❤️&lt;/p&gt;

</description>
      <category>futurechallenge</category>
      <category>ai</category>
      <category>career</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to Integrate PromPHP(Prometheus) with Laravel's Cache Facade in few Minutes 🚀</title>
      <dc:creator>Hussein El-Hewehi</dc:creator>
      <pubDate>Sun, 23 Mar 2025 12:31:15 +0000</pubDate>
      <link>https://dev.to/husseinhewehii/how-to-integrate-promphp-with-laravels-cache-facade-for-prometheus-2fi6</link>
      <guid>https://dev.to/husseinhewehii/how-to-integrate-promphp-with-laravels-cache-facade-for-prometheus-2fi6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In Laravel applications, &lt;a href="https://prometheus.io" rel="noopener noreferrer"&gt;&lt;strong&gt;Prometheus&lt;/strong&gt;&lt;/a&gt; is a powerful tool for monitoring and metrics collection, especially when using packages for Laravel Prometheus like &lt;a href="https://spatie.be/docs/laravel-prometheus/v1/installation-setup" rel="noopener noreferrer"&gt;Spatie's&lt;/a&gt;. However, Spatie's package (at the time of writing this article) doesn't support all Prometheus features like &lt;strong&gt;counters&lt;/strong&gt; &amp;amp; &lt;strong&gt;histograms&lt;/strong&gt;, even though the relevant methods are present in the &lt;strong&gt;Prometheus&lt;/strong&gt; class.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Issue ⚠️
&lt;/h2&gt;

&lt;p&gt;Typically, following the PromPHP package's convention for short-term storage requires configuring extensions like &lt;strong&gt;Redis&lt;/strong&gt; or &lt;strong&gt;APCu&lt;/strong&gt; for storing metrics. This may not be ideal for everyone, especially if you are already using Laravel’s &lt;strong&gt;Cache facade&lt;/strong&gt; for caching purposes.&lt;/p&gt;

&lt;p&gt;In this article, I'll show you how to integrate &lt;a href="https://github.com/PromPHP/prometheus_client_php" rel="noopener noreferrer"&gt;PromPHP&lt;/a&gt; with Laravel's Cache facade .&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgement 🙏
&lt;/h2&gt;

&lt;p&gt;This Tutorial is inspired by &lt;a href="https://betterstack.com/community/guides/monitoring/php-laravel-prometheus/" rel="noopener noreferrer"&gt;Ayooluwa Isaiah&lt;/a&gt; for Using Prometheus&lt;/p&gt;

&lt;p&gt;and, the custom Adapter was already implemented under the hood in the Spatie package to be used for Spatie usage, I copied &amp;amp; extended it 😉&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's get Started 🔥
&lt;/h3&gt;




&lt;h4&gt;
  
  
  Install the package:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require promphp/prometheus_client_php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create a provider:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:provider PrometheusServiceProvider
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Register the &lt;code&gt;PrometheusServiceProvider&lt;/code&gt;:
&lt;/h4&gt;

&lt;p&gt;Add the PrometheusServiceProvider in &lt;code&gt;config/app.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'providers' =&amp;gt; [
    // Other providers...
    App\Providers\PrometheusServiceProvider::class,
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create a Custom Adapter Class:
&lt;/h4&gt;

&lt;p&gt;This class is supposed to implement &lt;code&gt;Prometheus\Storage\Adapter&lt;/code&gt; interface, but since the package already has some classes that implement that Interface, we will inherit one &lt;code&gt;Prometheus\Storage\InMemory&lt;/code&gt; of them and override it, as following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Services;

use Illuminate\Contracts\Cache\Repository;
use Prometheus\Counter;
use Prometheus\Gauge;
use Prometheus\Histogram;
use Prometheus\MetricFamilySamples;
use Prometheus\Storage\InMemory;

class PrometheusCustomAdapter extends InMemory
{
    protected string $cacheKeyPrefix = 'PROMETHEUS_';

    protected string $cacheKeySuffix = '_METRICS';

    /** @var string[] */
    private array $stores = [
        'gauges' =&amp;gt; Gauge::TYPE,
        'counters' =&amp;gt; Counter::TYPE,
        'histograms' =&amp;gt; Histogram::TYPE,
    ];

    public function __construct(protected readonly Repository $cache)
    {
    }

    /**
     * @return MetricFamilySamples[]
     */
    public function collect(bool $sortMetrics = true): array
    {
        foreach ($this-&amp;gt;stores as $store =&amp;gt; $storeName) {
            $this-&amp;gt;{$store} = $this-&amp;gt;fetch($storeName);
        }

        return parent::collect($sortMetrics);
    }

    public function updateHistogram(array $data): void
    {
        $this-&amp;gt;histograms = $this-&amp;gt;fetch(Histogram::TYPE);
        parent::updateHistogram($data);
        $this-&amp;gt;update(Histogram::TYPE, $this-&amp;gt;histograms);
    }

    public function updateGauge(array $data): void
    {
        $this-&amp;gt;gauges = $this-&amp;gt;fetch(Gauge::TYPE);
        parent::updateGauge($data);
        $this-&amp;gt;update(Gauge::TYPE, $this-&amp;gt;gauges);
    }

    public function updateCounter(array $data): void
    {
        $this-&amp;gt;counters = $this-&amp;gt;fetch(Counter::TYPE);
        parent::updateCounter($data);
        $this-&amp;gt;update(Counter::TYPE, $this-&amp;gt;counters);
    }

    public function wipeStorage(): void
    {
        $this-&amp;gt;cache-&amp;gt;deleteMultiple(
            array_map(fn ($store) =&amp;gt; $this-&amp;gt;cacheKey($store), $this-&amp;gt;stores)
        );
    }

    protected function fetch(string $type): array
    {
        return $this-&amp;gt;cache-&amp;gt;get($this-&amp;gt;cacheKey($type)) ?? [];
    }

    protected function update(string $type, $data): void
    {
        $this-&amp;gt;cache-&amp;gt;put($this-&amp;gt;cacheKey($type), $data, 3600);
    }

    protected function cacheKey(string $type): string
    {
        return $this-&amp;gt;cacheKeyPrefix . $type . $this-&amp;gt;cacheKeySuffix;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Register the Custom Adapter:
&lt;/h4&gt;

&lt;p&gt;Update the &lt;code&gt;PrometheusServiceProvider&lt;/code&gt; by adding &lt;code&gt;App\Services\PrometheusCustomAdapter&lt;/code&gt; to the &lt;code&gt;Prometheus\CollectorRegistry&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Providers;

use Illuminate\Contracts\Cache\Repository;
use Illuminate\Support\ServiceProvider;
use App\Services\PrometheusCustomAdapter;
use Prometheus\CollectorRegistry;

class PrometheusServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this-&amp;gt;app-&amp;gt;singleton(CollectorRegistry::class, function ($app) {
            // typically, we would need to use one from the PromPHP package
            // $adapter = new \Prometheus\Storage\APC();
            // OR
            // $adapter = new \Prometheus\Storage\Redis($redisConfigurations);

            $adapter = new PrometheusCustomAdapter($app-&amp;gt;make(Repository::class));
            return new CollectorRegistry($adapter, false);
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create &lt;u&gt;Metrics&lt;/u&gt; Endpoint:
&lt;/h4&gt;

&lt;p&gt;Create new Endpoint &lt;code&gt;metrics&lt;/code&gt; to render the Metrics &lt;code&gt;routes/web.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

use Prometheus\CollectorRegistry;
use Prometheus\RenderTextFormat;

Route::get('/metrics', function (CollectorRegistry $registry) {
    $renderer = new RenderTextFormat();
    $metrics = $registry-&amp;gt;getMetricFamilySamples();
    if (empty($metrics)) {
        return response('No metrics found');
    }
    return response($renderer-&amp;gt;render($metrics))
        -&amp;gt;header('Content-Type', RenderTextFormat::MIME_TYPE);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This endpoint should render metrics in a Prometheus-compatible format.&lt;br&gt;
Open your browser &amp;amp; visit &lt;code&gt;http://localhost:8000/metrics&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As we haven't registered any metrics yet, we will get &lt;code&gt;No metrics found&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now Let's add some Metrics 🤓:&lt;/p&gt;
&lt;h4&gt;
  
  
  Add Metrics:
&lt;/h4&gt;
&lt;h5&gt;
  
  
  Create New Middleware
&lt;/h5&gt;

&lt;p&gt;Create New Middleware to Register Metrics&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:middleware PrometheusMiddleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Register Metrics
&lt;/h5&gt;

&lt;p&gt;Register Metrics in &lt;code&gt;app/Http/Middleware/PrometheusMiddleware.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Prometheus\CollectorRegistry;
use Prometheus\Counter;
use Prometheus\Exception\MetricsRegistrationException;

class PrometheusMiddleware
{
    private Counter $counter;

    /**
     * @throws MetricsRegistrationException
     */
    public function __construct(CollectorRegistry $registry)
    {
        $this-&amp;gt;counter = $registry-&amp;gt;getOrRegisterCounter(
            env('APP_NAME'),
            'http_requests_total',
            'Total count of HTTP requests',
            ['status', 'path', 'method']
        );
    }

    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        $this-&amp;gt;counter-&amp;gt;inc([
            'status' =&amp;gt; $response-&amp;gt;getStatusCode(),
            'path' =&amp;gt; $request-&amp;gt;path(),
            'method' =&amp;gt; $request-&amp;gt;method()
        ]);

        return $response;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Register Middleware:
&lt;/h4&gt;

&lt;p&gt;Register middleware in &lt;code&gt;app/Http/Kernel.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected $middleware = [
    // ...
    \App\Http\Middleware\PrometheusMiddleware::class,
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now refresh the Tab where &lt;code&gt;http://localhost:8000/metrics&lt;/code&gt; is one several times &amp;amp; try calling other endpoint several times, you'll see output like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"# HELP YOUR_APP_NAME_http_requests_total Total count of HTTP requests"&lt;br&gt;
"# TYPE YOUR_APP_NAME_http_requests_total counter"&lt;br&gt;
YOUR_APP_NAME_http_requests_total{status="200",path="metrics",method="GET"} 2&lt;br&gt;
YOUR_APP_NAME_http_requests_total{status="200",path="otherendpoint",method="GET"} 1&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  so far so good ? 🤔, Now let's test the Cache 🔍
&lt;/h5&gt;

&lt;h4&gt;
  
  
  Test our Laravel Caching:
&lt;/h4&gt;

&lt;p&gt;Clear the cache using Laravel&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan cache:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, Refresh &lt;code&gt;http://localhost:8000/metrics&lt;/code&gt;, and you should see &lt;code&gt;No metrics found&lt;/code&gt; again.&lt;/p&gt;




&lt;h2&gt;
  
  
  Congratulations !! 🎉
&lt;/h2&gt;

&lt;h2&gt;
  
  
  You're now Using the Laravel Cache with PromPHP 🎯
&lt;/h2&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>prometheus</category>
      <category>cache</category>
    </item>
  </channel>
</rss>
