"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Runtime Log Level Change using Golang & GoFr

Runtime Log Level Change using Golang & GoFr

Published on 2024-07-30
Browse:548

In this article, I will be sharing how you can change the log level of your application without restarting your application.

Introduction

Log levels are usually considered to be in order of importance: turn on "unimportant" levels in development (notice, debug and the like), but enable only the "most important" levels (warn, error, etc.) in production, where resources like CPU time and disk space are precious.

But what if your application is running at ERROR level and you start facing many issues, but you cannot figure it out from ERROR level logs, changing the log level by redeploying the application will take a lot of time and resources.

Moreover, running your application at either INFO or DEBUG level in production will generate a large number of logs which can overwhelm the logging system, leading to increased I/O operations and resource consumption.

To rescue us from these issues, GoFr - The Ultimate Golang Framework provides a secure way to change the log level without restarting your application.

Changing Log Level

To change the log level any GoFr application requires the following configuration:

REMOTE_LOG_URL= (e.g., https://log-service.com/log-levels?id=1)

GoFr fetches the endpoint provided every 15 seconds by default to get the latest log level, this interval can be increased or decreased by adding the following configuration.

REMOTE_LOG_FETCH_INTERVAL= (default: 15)

Log Level Service

GoFr requires the response from the URL in the following format with two mandatory fields:

{
    "data": {
       "serviceName": "test-service",
       "logLevel": "DEBUG"
    }
}

Let's create the log-level service which will provide the log-level to our application.

I will be using GoFr to create the service, refer the documentation to know more.

We will use MySQL as the database, to add MySQL add the following configs in .env file in the configs directory.

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=password
DB_NAME=log-level
DB_PORT=2001
DB_DIALECT=mysql

To run the MySQL docker container run the following command

docker run --name gofr-logger -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=log-level -p 2001:3306 -d mysql:8.0.30

Lets add the main.go file with migrations to create table and we will use AddRESTHandler feature to register the route.

main.go

package main

import (
 "gofr.dev/pkg/gofr"
 "gofr.dev/pkg/gofr/migration"
)

const createTable = `CREATE TABLE level (
    id INT PRIMARY KEY,
    service_name VARCHAR(255) NOT NULL,
    log_level VARCHAR(50) NOT NULL
);
`

func createTableLevel() migration.Migrate {
 return migration.Migrate{
  UP: func(d migration.Datasource) error {
   _, err := d.SQL.Exec(createTable)
   if err != nil {
    return err
   }

   return nil
  },
 }
}

type Level struct {
 ID          int    `json:"id"`
 ServiceName string `json:"serviceName"`
 LogLevel    string `json:"logLevel"`
}

func (u *Level) RestPath() string {
 return "level"
}

func main() {
 app := gofr.New()

 app.Migrate(map[int64]migration.Migrate{1: createTableLevel()})

 err := app.AddRESTHandlers(&Level{})
 if err != nil {
  app.Logger().Fatalf("Failed to register routes for level struct: %v", err)
 }

 app.Run()
}

After running the Log Service we will see the following logs:

LOGS FOR LOG-LEVEL CHANGE SERVICE STARTUP

We have all the REST routes registered.

To Create a service send the following request:

curl --location 'localhost:8000/level' \
--header 'Content-Type: application/json' \
--data '{
    "id":1,
    "logLevel":"INFO",
    "serviceName":"gofr-app"
}'

To Update the log level send the following request:

curl --location --request PUT 'localhost:8000/level/1' \
--header 'Content-Type: application/json' \
--data '{
    "id":1,
    "logLevel":"DEBUG",
    "serviceName":"gofr-app"
}'

To Get the log level send the following request:

curl --location 'localhost:8000/level/1'

The same URL will be used in the configs of our application whose log-level has to be changed remotely.

CONCLUSION

By using GoFr remote Log Level change feature, you will get benefits such as:

  • Effortless Adjustments:
    Modify the log level anytime without restarting the application. This is especially helpful during troubleshooting.

  • Enhanced Visibility:
    Easily switch to a more detailed log level (e.g., DEBUG) to gain deeper insights into specific issues, and then switch back to a less detailed level (e.g., INFO) for regular operation.

  • Improved Performance:
    Generating a large number of logs can overwhelm the logging system, leading to increased I/O operations and resource consumption, changing to Warn or Error Level reduces the number of logs, and enhancing performance, and REDUCING CLOUD COST.

Support GoFr by giving a ⭐star: https://github.com/gofr-dev/gofr

Moreover, you have access to the free public endpoint to export and view your application's traces @ tracer.gofr.dev. 
To enable it, add the following config in your .env file

TRACE_EXPORTER=gofr

Other Benefits:
If you contribute towards GOFR either in development or writing articles. You can get free swags(T-shirts, Stickers) by filling out the form presented on their GitHub Readme (at the bottom).

Release Statement This article is reproduced at: https://dev.to/aryanmehrotra/remote-runtime-log-level-change-using-golang-gofr-54d8?1 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3