Implement Logging in Angular with Firebase

Hi Friends, This is Lakshman here.

Welcome back to the Series Angular Best Practices

Today, We will Implement Logging for your angular app.

Every Application required Logging irresptive of Application. Its either Front-End or Back-End.

For Back-End, we have lots of packages and SDK available for such as Serilog, Log4Net for .NET Core, Framework.

However, In Front-End we need to Store your Logs somewhere in NoSQL Database where we can query the logs.

Today we are going to use FireBase Cloud Database to Store our logging. As its Client-side SDK.

Our other options are

  1. Application Insights (Microsoft Azure)
  2. JSLog with Seq. etc.,

Pre-requisites:

The pre-requisites are

For Code Editor its VS Code.

Implementation:

We will go there the Implementation by Steps,

Step 1: Create the Cloud FireBase Database - Click Here

Step 2: Add Web Client for Project via Steps

Step 3: Copy the Client Configuration consist like below,

var firebaseConfig = {
  apiKey: "#APIKey",
  authDomain: "***.firebaseapp.com",
  databaseURL: "https:/***..firebaseio.com",
  projectId: "#ProjectId",
  storageBucket: "***.appspot.com",
  messagingSenderId: "#MessageSenderId",
  appId: "1:331411129042:web:b87de2f71d73a2294c230b",
  measurementId: "G-***",
};

Step 4. Copy Config to Environment Configuration File as below,

export const environment = {
  ...
  Logging: {
      IsFirebase: true,
      LogLevel: "Warn"
  },
  FireBase: {
      apiKey: "#APIKey",
      authDomain: "***.firebaseapp.com",
      databaseURL: "https:/***..firebaseio.com",
      projectId: "#ProjectId",
      storageBucket: "***.appspot.com",
      messagingSenderId: "#MessageSenderId",
      appId: "1:331411129042:web:b87de2f71d73a2294c230b",
      measurementId: "G-***",
  },
};

On Logging we have Feature Flag Concept. If IsFirebase Set to True it will log to FireBase vice versa as per the LogLevel.

Step 5. Once the Configuration is Done Add Below NPM Packages

  • @angular/fire
  • firebase
npm install --save firebase @angular/fire

Step 6. Create the Logging Service Files with below command

npm run ng generate service logging

Step 7. Add below code to logger.service.ts

import { Injectable } from "@angular/core";
import { AngularFirestore } from "@angular/fire/firestore";
import { environment } from "src/environments/environment";

@Injectable({
  providedIn: "root",
})
export class LoggingService {
  level: LogLevel = LogLevel.All;

  constructor(private firestore: AngularFirestore) {}

  debug(msg: string, rawdata?: any, ...optionalParams: any[]) {
    this.writeToLog(msg, rawdata, LogLevel.Debug, optionalParams);
  }

  info(msg: string, rawdata?: any, ...optionalParams: any[]) {
    this.writeToLog(msg, rawdata, LogLevel.Info, optionalParams);
  }

  warn(msg: string, rawdata?: any, ...optionalParams: any[]) {
    this.writeToLog(msg, rawdata, LogLevel.Warn, optionalParams);
  }

  error(msg: string, rawdata: any, ...optionalParams: any[]) {
    this.writeToLog(msg, rawdata, LogLevel.Error, optionalParams);
  }

  fatal(msg: string, rawdata: any, ...optionalParams: any[]) {
    this.writeToLog(msg, rawdata, LogLevel.Fatal, optionalParams);
  }

  log(msg: string, rawdata?: any, ...optionalParams: any[]) {
    this.writeToLog(msg, rawdata, LogLevel.All, optionalParams);
  }

  setlogLevel(level: LogLevel) {
    this.level = level;
  }

  private writeToLog(
    msg: string,
    rawdata: Error,
    level: LogLevel,
    params: any[]
  ) {
    if (this.shouldLog(level)) {
      let value: Ilogger = {} as Ilogger;

      value.LogDate = JSON.stringify(new Date());
      value.LogLevel = LogLevel[level];
      value.Message = msg;
      if (rawdata) {
        value.RawData = rawdata.stack;
      }
      if (params.length) {
        value.OptionalParams = JSON.stringify(params).toString();
      }

      if (environment.Logging.IsFirebase) {
        this.LogToFireBase(value);
      }

      // Log the value
      console.log(value);
    }
  }

  private shouldLog(level: LogLevel): boolean {
    let ret: boolean = false;
    if (
      (level >= this.level && level !== LogLevel.Off) ||
      this.level === LogLevel.All
    ) {
      ret = true;
    }
    return ret;
  }

  private LogToFireBase(val: Ilogger) {
    this.firestore.collection("logging").add({ ...val });
  }

  getAllLogs() {
    return this.firestore.collection("logging").snapshotChanges();
  }
}

export interface Ilogger {
  loggerId: string;
  LogDate: string;
  LogLevel: string;
  Message: string;
  OptionalParams: any;
  RawData: any;
}

export enum LogLevel {
  All = 0,
  Debug = 1,
  Info = 2,
  Warn = 3,
  Error = 4,
  Fatal = 5,
  Off = 6,
}

In the Above Code We have handling the Error Log level to FireBase and stores all logs in colletion logging in Firebase Cloud Database.

Step 8. Add Logging Server and Fire Base Module to Provider as below Code in app.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { environment } from 'src/environments/environment';
import { LoggingService } from './logging.service';

@NgModule({
...
imports: [
    CommonModule,
    ...
    AngularFireModule.initializeApp(environment.FireBase),
    AngularFirestoreModule,
    ...
],
providers: [
    ...
    LoggingService
]
...
})
export class AppModule { }

Step 9. Set the Log Level for Logging Service in App Component as shown in below Code

import { Component, OnInit } from "@angular/core";
import { environment } from "src/environments/environment";
import { LoggingService, LogLevel } from "./logging/logging.service";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"],
})
export class AppComponent implements OnInit {
  constructor(private logService: LoggingService) {}
  title = "ngAngularPractices";

  ngOnInit() {
    this.logService.level = LogLevel[environment.Logging.LogLevel];
  }
}

Once all the steps completed. We can start using this service any across you module with Injection option to log our error. All the logs will be saved to Firebase.

You may also access to source on GitHub by Click Here

On-road head, we will discuss a lot of things.

Looking forward to your comments and share your feedback.

Until that, I am Lakshman, Signing Off.

Comments

  1. Thank you so much for this best knowledge. I really like your work and research about cloud migration houston tx . You give us best knowledge by your blog and I agree with your point of view, keep it up.

    ReplyDelete

Post a Comment

Popular posts from this blog

Model Mapper in Angular

Dockerize Angular App for Dev