Observability in Software Engineering Part 2

In the first part of this series, we introduced observability and discussed its significance, particularly in microservice architectures. Now, we shift our focus to the tools that will bring observability to life: Grafana and Prometheus. These are powerful platforms that allow us to visualize and monitor our systems effectively. In this post, we will introduce key observability concepts that one must understand before diving deeper into Grafana and Prometheus. Grafana Grafana is an open-source platform for monitoring and observability, primarily used to visualize metrics, logs, and traces through customizable dashboards....

September 22, 2024 · 4 min

Observability in Software Engineering Part 1

In today’s software development landscape, ensuring system reliability, performance, and scalability is crucial. With the increase in complexity of modern systems, traditional monitoring methods are no longer sufficient. Observability was introduced as a critical practice that allows engineers to gain deeper insights into their systems and diagnose issues effectively. This is the first post of a series about observability in software engineering. In this first post, we will explore what observability means, its historical evolution, its importance in modern architectures, and why observable systems outperform those without observability....

September 21, 2024 · 4 min

About hacky solutions

A strange, and maybe funny, phenomenon that I notice after 10 years working in this industry is that developers can get really offended when someone calls out their solution as a hack. I’ve observed this in different companies, even some people who I consider calm and composed can get their attitude changed once I tell them that their solution is hacky. People tend to be very civil as long as I politely criticize their work in a friendly manner, but once the word “hack” is said, it’s as if I was personally attacking them....

April 7, 2024 · 3 min

Facade Design Pattern

In the previous post, we converted an incompatible interface ino another that fits nicely with our existing design thanks to the adapter pattern. We were able to design a weapon system that allows composing different damage types to different weapons, and also able to incorporate a third party library to add a specific type of weapon damage. While the exising solution works, it’s not very clean due to a few reasons....

March 24, 2024 · 4 min

Adapter Design Pattern

In our previous post, we leveraged the decorator design pattern to implement a weapon system for our next video game. Thanks to the decorator pattern, we were able to provide additional damage types to our weapons without changing the weapons’ implementation. Adding a new weapon therefore is very easy, and so is adding a new damage type. In this post, we’ll cover a different kind of problem that can be solved by the adapter design pattern....

March 17, 2024 · 4 min

Decorator Design Pattern

The decorator design pattern lets us provide additional behavior to a type. This design pattern is extremely powerful when we want to provide extra functionalities without requiring changes to an existing type, helping us achieve the Open Closed principle. In this post we’ll examine how the decorator design pattern handles a hypothetical problem. The code will be written in Golang, but the idea should be simple enough to port to other programming languages....

February 1, 2024 · 5 min

Contextual Error Handling in Go

Go provides 2 native ways to instatiate an error value: errors.New that returns a string error value, very useful to create a simple sentinel error value like var errNotFound = errors.New("record not found"). fmt.Errorf that may return an error that wraps another error, and the wrapped error can be asserted against with errors.Is, or retrieved with errors.As. While both approaches are fine for simple programs, they lack depth when it comes to large systems because of:...

October 13, 2023 · 2 min

Interface Pollution

In this article, we’ll look at a very common mistake that Golang new comers make, especially when they come from a background of Object Oriented Programming (OOP) languages like Java or C#. What is interface pollution? Let’s look at some codes. package employee type Employee struct { Name string Credit int } type EmployeeRepository interface { Query(name string) *Employee } func NewEmployeeRepository() EmployeeRepository { return &database{} } type database struct {} // Query returns the first Employee that has a matching name....

June 24, 2023 · 5 min

Value and Pointer Semantic

“How do you decide that a variable should be a pointer, or a value?” and “How do you know when to use pointer receiver and value receiver of a method?” are among the most common questions I receive from Go new comers. Even though there is no offical rule that dictates which types should use pointer, and which types should use value, it’s worth to deep dive into the topic of pointer and value semantic in Go, which is what we’ll do in this article....

June 1, 2023 · 7 min

About Single Responsibility Principle

Single Responsibility Principle (SRP) is the first one of the 5 famous principles that make up SOLID, a classic guideline to write clean and maintainable code, worshipped by a plethora of programmers worldwide. There exists various articles and workshops out there to explain the principle. Tech celebs support it, talk about it in social platforms. Many articles, however, does a poor job explaining the principle, resulting in a shallow and rigid understanding of the principle among developers....

April 6, 2023 · 5 min