Sunday 6 February 2022

Micro-Frontend Architecture Pattern

Micro-Frontends (MFE) are the technical representation of a business subdomain, they allow independent standalone implementations for a domain area. 


Microsoft Defender for Cloud for B2B SaaS solution based on Azure PaaS

Microsoft Defender for Cloud were previously called Azure Security Center and Azure Defender.  Its function is hardening via suggestions and actively monitoring (and stopping) usage.  Azure SQL has it's own defender, and Microsoft Defender uses the same SQL tooling as part of it.  It's a great tool, while it can be expensive, even turn on in production for set periods and then deactivate.

Two tiers of Microsoft Defender for the Cloud:

  • Free - Continuous assessment & Hardening suggestions
  • Paid - Same as free but also can apply suggestions and active threat prevention.

Enable it for specific services, at the service level it is all or nothing, so if you have 40 app service instances, it's monitor all or nothing $$$

Microsoft Defender for Cloud - an introduction | Microsoft Docs

Monday 24 January 2022

CorrelationId thoughts for improved logging in SPAs

Problem:  Single Page Applications (SPA) generate a new correlationId/guid on path changes only, when logging to something like App Insights, the SPA using a framework like Angular will have a page view with multiple actions that are logged using the same guid.  

Initial Hypothesis: You can work out the users journey by using the page view guid and tracing the actions to drill down to the issue.  It is far easier to generate a new guid for each action making error tracing simpler/faster for 1st line support.  Also performance issues are far easier to replicate and automate reporting on for changes in performance.   

SPA/Angular Resolution:

  1. import{ Injectable } from'@angular/core'; 

  1. import{ ApplicationInsights } from'@microsoft/applicationinsights-web'; 

  1. import{ environment } from'src/environments/environment'; 

  1.  

  1. @Injectable({ 

  1.   providedIn:'root' 

  1. }) 

  1. exportclassAppinsightsLoggingService { 

  1.   appInsights: ApplicationInsights; 

  1.   constructor() { 

  1.     this.appInsights = newApplicationInsights({ 

  1.       config: { 

  1.         instrumentationKey:environment.appInsights.instrumentationKey, 

  1.         enableRequestHeaderTracking:true, 

  1.         enableCorsCorrelation:true, 

  1.         loggingLevelTelemetry:1, 

  1.         enableAutoRouteTracking:true// option to log route changes 

  1.       } 

  1.     }); 

  1.     this.appInsights.loadAppInsights(); 

  1.     this.appInsights.trackPageView(); 

  1.   } 

  1.  

  1.   logPageView(name?: string, url?: string) { // option to call manually 

  1.     alert(name); 

  1.     this.appInsights.trackPageView({ 

  1.       name:name, 

  1.       uri:url 

  1.     }); 

  1.   } 

  1. } 


  1. public getTraceId (){ 

  1.     returnthis.appInsights.context.telemetryTrace.traceID; 

  1.   } 

  2. // Call when needed


Note: Thanks to Pravesh Chourasia for showing me how to do this.