<?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: Mark Khuzam</title>
    <description>The latest articles on DEV Community by Mark Khuzam (@markkdev).</description>
    <link>https://dev.to/markkdev</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%2F541235%2F6635ca94-b69f-4303-8f0b-b4c8e973826a.jpg</url>
      <title>DEV Community: Mark Khuzam</title>
      <link>https://dev.to/markkdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/markkdev"/>
    <language>en</language>
    <item>
      <title>One Kind of Platform Engineer</title>
      <dc:creator>Mark Khuzam</dc:creator>
      <pubDate>Thu, 01 Dec 2022 17:00:26 +0000</pubDate>
      <link>https://dev.to/markkdev/one-kind-of-platform-engineer-55i8</link>
      <guid>https://dev.to/markkdev/one-kind-of-platform-engineer-55i8</guid>
      <description>&lt;p&gt;Platform Engineering is hot again! I think...&lt;/p&gt;

&lt;p&gt;I've been seeing a lot of information coming out about Platform Engineering being an "emerging field".&lt;/p&gt;

&lt;p&gt;Ok, but it's not really.&lt;/p&gt;

&lt;p&gt;While I don't necessarily consider myself only a "Platform Engineer", I am a Software Engineer that works on a platform team.&lt;/p&gt;

&lt;p&gt;I want to share a bit about my experience working in this discipline over the last few years.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Platform Engineer?
&lt;/h2&gt;

&lt;p&gt;According to GPT-3: Platform engineers are responsible for designing, building, and maintaining software platforms used by companies to build applications and services. Platform engineering is a specialized field of engineering that requires a combination of technical and managerial skills.&lt;/p&gt;

&lt;p&gt;Nice, that kind of makes sense.&lt;/p&gt;

&lt;p&gt;In layman terms, your customers are the developers building the product. Your products are the tools that enable them to build more, build faster, and build with less bugs. &lt;/p&gt;

&lt;h2&gt;
  
  
  What skills do you need to become a Platform Engineer?
&lt;/h2&gt;

&lt;p&gt;This is where things get blurry.&lt;/p&gt;

&lt;p&gt;Platform Engineering is very specific to the company you work for, the tech stack you use to develop, and the CI/CD tools at your disposal.&lt;/p&gt;

&lt;p&gt;For me, I started with a fairly common Web Development background.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript / TypeScript&lt;/li&gt;
&lt;li&gt;React / HTML / CSS&lt;/li&gt;
&lt;li&gt;GraphQL&lt;/li&gt;
&lt;li&gt;Express&lt;/li&gt;
&lt;li&gt;Insert flavor of State Management&lt;/li&gt;
&lt;li&gt;Insert flavor of Database (SQL, NoSQL, KindOfSQL*)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I mentioned before, Platform Engineering is heavily intertwined with the tech stack your company uses.&lt;/p&gt;

&lt;p&gt;Where it gets more interesting is when you throw some more tools into the mix.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Webpack &amp;lt;- but like actually how it works&lt;/li&gt;
&lt;li&gt;Shell Scripting&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;li&gt;Visibility (Grafana | Kibana | Datadog | StatsD | etc.)&lt;/li&gt;
&lt;li&gt;CI/CD Tools (TeamCity | GitLab | Github Actions | Jenkins | etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list goes on but I'll stop here.&lt;/p&gt;

&lt;p&gt;Do you feel like I'm just listing out every technology you see in bloated job descriptions?&lt;/p&gt;

&lt;p&gt;I kind of am and it's all actually kind of necessary.&lt;/p&gt;

&lt;p&gt;Oh I forgot one other thing.. &lt;strong&gt;Systems Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, after learning how to use the tools I just mentioned and figuring out how they fit together, the products you build have to optimize and fit into the overall system design.&lt;/p&gt;

&lt;h2&gt;
  
  
  This Sounds Like 3 Jobs In One
&lt;/h2&gt;

&lt;p&gt;Mostly because it can be. Remember you've got to understand the product code, how to bundle it, containerize it, test it, deploy it, and have visibility on your system when it's in production.&lt;/p&gt;

&lt;p&gt;Yeah, it's a lot.&lt;/p&gt;

&lt;p&gt;Platform Engineering sits in between a Product Developer, DevOps Engineer, and a Site Reliability Engineer.&lt;/p&gt;

&lt;p&gt;Knowledge in each of these categories is required and the depth of knowledge can vary greatly depending on the task at hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Day to Day Work (My Kind)
&lt;/h2&gt;

&lt;p&gt;My team maintains a few different platforms. &lt;/p&gt;

&lt;p&gt;I'll emphasize maintain here because it's our responsibility to upgrade packages used by the platform and make sure that any breaking changes are identified and supported across the platform.&lt;/p&gt;

&lt;p&gt;This can be anything from upgrading React or Apollo, keeping up with the latest versions of Node, or deprecating a testing library like Enzyme across an entire codebase.&lt;/p&gt;

&lt;p&gt;Visibility is huge, if you can't see what's happening to your application while in production, optimizing it is impossible.&lt;/p&gt;

&lt;p&gt;Site went down? Your metrics should tell you why and how to fix it.&lt;/p&gt;

&lt;p&gt;Code quality, not just eslint and prettier, you're looking to see that anti-patterns aren't being created and that the codebase follows a predictable design pattern.&lt;/p&gt;

&lt;p&gt;Middleware and shared component libraries fall under the category of infrastructure and it's our job to make sure everyone is on the same page with these.&lt;/p&gt;

&lt;p&gt;Webpack, oh webpack, it can't all be sunshine and rainbows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Is a Fit For Platform Engineering?
&lt;/h2&gt;

&lt;p&gt;To be honest, when I started my current role I didn't know that this is what I would be doing, but this is the type of work I've always enjoyed doing.&lt;/p&gt;

&lt;p&gt;Folks that I've seen succeed in Platform Engineering are interested in&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Software Architecture &lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - How the entire system fits together and functions as a whole
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Codebase Scalability&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; - What abstractions/tooling/design patterns can I build to make a growing/large codebase maintainable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Eager to Learn&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- How does this OSS library work?
- Reading source code if documentation isn't clear or not available.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Excited About Exploring&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- As new technologies emerge, you're someone that likes to experiment and weigh the cost/benefit of adopting them
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Willing to Assist and Mentor&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Often you'll feel like the tech support for the people building the tech.

&lt;ul&gt;
&lt;li&gt;Your decisions directly affect the day to day of the product development teams you support
&lt;/li&gt;
&lt;/ul&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;


Final Thoughts
&lt;/h2&gt;


&lt;p&gt;It's a fun discipline if you like to be challenged. &lt;/p&gt;

&lt;p&gt;If you're feeling bored or that your day-to-day work is repetitive, Platform Engineering is a route that's always full of new and interesting problems to be solved.&lt;/p&gt;

&lt;p&gt;Success here comes from making sure your co-workers are informed, supported, and can execute.&lt;/p&gt;

&lt;p&gt;I'm happy to answer questions or write a follow-up if there's interest.&lt;/p&gt;

&lt;p&gt;Find me on Twitter &lt;a href="https://twitter.com/markkdev" rel="noopener noreferrer"&gt;@markkdev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.markk.dev/blogs/one-kind-of-platform-engineer" rel="noopener noreferrer"&gt;Original post&lt;/a&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Setting Up Google Analytics with React Context in Next.js</title>
      <dc:creator>Mark Khuzam</dc:creator>
      <pubDate>Wed, 16 Dec 2020 01:04:53 +0000</pubDate>
      <link>https://dev.to/markkdev/setting-up-google-analytics-with-react-context-in-next-js-23h1</link>
      <guid>https://dev.to/markkdev/setting-up-google-analytics-with-react-context-in-next-js-23h1</guid>
      <description>&lt;p&gt;Google Analytics is a free tool offered by Google to assist you in analyzing your web traffic. The topic of Analytics and User Tracking is a pretty deep dive and out of the scope of this tutorial, if you'd like to learn more about Analytics, &lt;a href="https://medium.com/analytics-for-humans/what-is-google-analytics-and-why-is-it-important-to-my-business-8c083a9f81be"&gt;this&lt;/a&gt; article offers a good starting point for what Google Analytics is and why it's important to your business.&lt;/p&gt;

&lt;p&gt;If you're completely new to GA, you'll want to visit the &lt;a href="https://analytics.google.com"&gt;application&lt;/a&gt; and set up an account. (GMail required)&lt;/p&gt;

&lt;p&gt;After you're done signing up, you'll be provided with a &lt;strong&gt;Tracking ID&lt;/strong&gt; for your website.&lt;/p&gt;

&lt;p&gt;It should look something like&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;UA-XXXXXXXX-X&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  React + Google Analytics
&lt;/h2&gt;

&lt;p&gt;There are many great tutorials about setting up GA in a React application, and most will get you to where you need. Where this tutorial differs is the use of React Context.&lt;/p&gt;

&lt;p&gt;By utilizing a Context, we can keep a React State object that holds information to handle multiple use cases, such as, a unique User ID, multiple GA Tracking ID's, user provided Tracking ID's, and more.&lt;/p&gt;

&lt;p&gt;To handle communicating with GA we'll use a popular utility library, &lt;a href="https://github.com/react-ga/react-ga"&gt;react-ga&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Installing the library can be done by using the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    yarn add react-ga
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating the Context
&lt;/h3&gt;

&lt;p&gt;We'll start by creating a Tracking Context which will be used to provide our App with the an API for logging events as well as initializing GA when the app loads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // contexts/trackers.jsx
    import React from  'react';

    const TrackingID = 'UA-XXXXXXXX-X';

    const TrackingContext = React.createContext();

    function TrackingProvider(props) {
        return &amp;lt;TrackingContext.Provider {...props} /&amp;gt;
    }

    const useTracking = () =&amp;gt; React.useContext(TrackingContext);

    export { TrackingProvider, useTracking };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Up to this point, what we've done is create a Context that we can use to wrap Components that will utilize tracking. Most applications will benefit from wrapping the entire application with a Tracking Context but use cases will vary so I recommend applying it where you think is best for your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrating into Next.js
&lt;/h2&gt;

&lt;p&gt;Next.js is an wonderful React framework that offers a quick way to implement SSR (server side rendering). If you've never used Next before, I recommend following their &lt;a href="https://nextjs.org/learn/basics/create-nextjs-app"&gt;Create a Next.js App tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To provide tracking to all of our components, we'll need to use the Tracking Provider in a custom next app file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // pages/_app.js

    import { TrackingProvider } from './contexts/tracking'

    function App({ Component, pageProps }) {
        return &amp;lt;AllYourOtherProviders&amp;gt;
                    &amp;lt;TrackingProvider&amp;gt;
                        &amp;lt;Component {...pageProps} /&amp;gt;
                    &amp;lt;/TrackingProvider&amp;gt;
            &amp;lt;/AllYourOtherProviders&amp;gt;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that the rest of our App has access to our TrackingProvider, we can start to initialize Google Analytics and track all page views that occur within the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // contexts/trackers.jsx

    import React, { useState, useEffect } from  'react';
    import Router from 'next/router'

    const TrackingID = 'UA-XXXXXXXX-X';
    const TrackingContext = React.createContext();

    function TrackingProvider(props) {
        // if the userId is passed in, we'll need to keep track of any
        // login/logout changes
        // another method is presented below, this will vary depending
        // on your authentication method
        const { userIdThatMightChange } = props

        // we create a default state to keep track of whether GA
        // has been initialized, if we're tracking a unique user,
        // and to hold all of our trackers

        const [analytics, setAnalytics] = useState({
            isInitialized: false,
            hasUser: false,
            trackers: ['myDefaultTracker']
        })

        // We create a function handle all route changes that occur
        // and track a users movements across pages in our app

        const handleRouteChange = url  =&amp;gt; {
            ReactGA.set({ page:  url }, analytics.trackers);
            ReactGA.pageview(url, analytics.trackers);
        };

        // We only want to initialize GA on the client side
        // This will fail if you're trying to initialize server side
        // useEffect will help us handle this case as it only runs
        // client side

        useEffect(() =&amp;gt; {
            const { isInitialized, hasUser, trackers } = analytics

            // How you detect which user is currently logged in
            // depends on the way you've set up authentication within
            // your app, the important thing is getting the userId

            const userId = getUserFromApi()

            // initialize GA with our tracking id
            // uncomment the user tracking method that works for you

            if (!isInitialized) {
                ReactGA.initialize(TrackingID, {
                    ...variousOptions,
                    gaOptions: {
                        userId: userId,
                        // userId: userIdThatMightChange
                    }
                })

                // Handle all route changes

                Router.events.on('routeChangeComplete', handleRouteChange);

                setAnalytics(prev  =&amp;gt; ({
                    ...prev,
                    isInitialized:  true,
                    hasUser:  Boolean(userId)
                }));

                // in case we dont have the user initially,
                // we handle setting a user in our tracker

            } else if (isInitialized &amp;amp;&amp;amp; !hasUser) {
                ReactGA.set({ userId }, trackers)

                setAnalytics(prev  =&amp;gt; ({
                    ...prev,
                    hasUser:  Boolean(userId)
                }));
            }

            return () =&amp;gt; {
                // clean up
                Router.events.off('routeChangeComplete', handleRouteChange);
            }
        }, [userIdThatMightChange])

        return &amp;lt;TrackingContext.Provider {...props} /&amp;gt;
    }

    const  useTracking = () =&amp;gt;  React.useContext(TrackingContext);

    export { TrackingProvider, useTracking };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you've made it this far, great!&lt;/p&gt;

&lt;p&gt;So far we've:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialized Google Analytics&lt;/li&gt;
&lt;li&gt;Are tracking unique users in our App&lt;/li&gt;
&lt;li&gt;Are tracking all page changes within our app&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now what remains is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] logging specific events that occur within the app&lt;/li&gt;
&lt;li&gt;[ ] adding multiple trackers to GA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adding Multiple Trackers
&lt;/h3&gt;

&lt;p&gt;Advanced analytics will require multiple trackers whether for users or for your own business. Extending the GA trackers requires another trackingId as well as naming each of trackers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // contexts/trackers.js

    function TrackingProvider(props) {
        ...
        // We'll define our addTracker function before useEffect
        const addTracker = (trackerId, trackerName) =&amp;gt; {
          if (analytics.isInitialized) {
            ReactGA.addTrackers([
                {
                    trackingId:  trackerId,
                    gaOptions: {
                        name:  trackerName
                    }
                }
            ]);
            setAnalytics((prev) =&amp;gt; ({
                ...prev,
                trackers: [...prev.trackers, trackerName]
            }))
          }
        }
        const removeTracker = (trackerName) =&amp;gt; {
            if (analytics.isInitialized) {
            setAnalytics((prev) =&amp;gt; ({
                ...prev,
                trackers: prev.trackers.filter((tracker) =&amp;gt; tracker !== trackerName)
            }))
            }
        }
        useEffect(() =&amp;gt; {
            ...
        })
        ...
        return &amp;lt;TrackingContext.Provider 
            value={{ addTracker, removeTracker }}
            {...props}
            /&amp;gt;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Logging Events in our Application
&lt;/h3&gt;

&lt;p&gt;We'll extend our TrackingContext with a logEvent method. This will allow us to have access to our tracking utility while keeping track of whether GA is initialized and the current user accessing it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // contexts/trackers.js

    function TrackingProvider(props) {
        ...
        // We'll define our logEvent function before useEffect
        const logEvent = ({ category = '', action = '', label = '' }) =&amp;gt; {
          if (analytics.isInitialized) {
              ReactGA.event({
              category,
              action,
              label
              }, analytics.trackers)
          }
        }
        useEffect(() =&amp;gt; {
        ...
        })
        ...
        return &amp;lt;TrackingContext.Provider 
            value={{ logEvent, addTracker, removeTracker }}
            {...props}
            /&amp;gt;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ReactGA offers more information on the type of data you can send to Google Analytics. I recommend reviewing their &lt;a href="https://github.com/react-ga/react-ga"&gt;documentation&lt;/a&gt; to extend it to your use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using logEvent in your components
&lt;/h3&gt;

&lt;p&gt;To use the tracker, we'll import our useTracking method into the components where specific events occur. This example component submits a form (use your imagination for the rest of the code)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // components/form.jsx

    import { useTracking } from 'contexts/tracker' 

    function Form(props) {
        const { logEvent } = useTracking()
        return &amp;lt;form onSubmit={() =&amp;gt; {
                // code that does something to submit data
                logEvent({
                    category: 'ExampleCategory',
                    action: 'Submitted Data',
                    label: 'Special Label'
                    })
            }}&amp;gt;
                &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
            &amp;lt;/form&amp;gt;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks for following along!&lt;/p&gt;

&lt;p&gt;This setup is a little more than what's required but extending tracking to use a unique user and localizing event logging greatly benefits the scalability of your application and decreases logging complexity.&lt;/p&gt;

&lt;p&gt;Extend the tracking context even more by integrating a &lt;a href="https://www.facebook.com/business/learn/facebook-ads-pixel"&gt;Facebook Pixel&lt;/a&gt; and other tracking utilities like &lt;a href="https://segment.com"&gt;Segment&lt;/a&gt; and &lt;a href="https://mixpanel.com"&gt;MixPanel&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Check out the original posting &lt;a href="https://markk.dev/blogs/setting-up-google-analytics-react-next-js"&gt;here&lt;/a&gt; and follow me on &lt;a href="https://twitter.com/markkdev"&gt;twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>analytics</category>
      <category>react</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
