Azure Static Web Apps have the possibility to create "Staging environments" automatically for new PullRequests done via GitHub.
This works quite well, however with the problem that when monitoring gets enabled via Azure Application Insights, all of the traces
and exceptions
of the "productive" SWA application and all of the currently deployed staging environments are appended in the same log tables (e.g. in traces
).
Is it possible to somehow select the environment as a column or create a KQL query which filters e.g. only for "production"?
I am aware that I also could configure a separate Application Insights instance for each created staging environment - but then I would have to adjust the APPINSIGHTS_INSTRUMENTATIONKEY
application setting differently for each newly created environment (which by default just copies the settings from "production" when a new PR is created).
I ended up solving this in the following way:
const envName = "__ENVIRONMENT_NAME__";
*.ts
files via find
+ -exec sed
with the branch name: - name: Get branch name (merge)
if: github.event_name != 'pull_request'
shell: bash
run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV
- name: Get branch name (pull request)
if: github.event_name == 'pull_request'
shell: bash
run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV
- name: Inject environment name in api function files
run: |
find ./api -name "*.ts" -not -path "./api/node_modules/*" -exec sed -i "s@__ENVIRONMENT_NAME__@${{ env.BRANCH_NAME }}@g" {} +
Context.Logger
:import { Logger } from "@azure/functions"
const envName = "__ENVIRONMENT_NAME__"; // injected via GH actions build
export class MyLogger {
private azLogger: Logger;
constructor(realLogger: Logger) {
this.azLogger = realLogger;
}
public error(...args: any[]): void {
const first = args.shift();
if (args.length > 0) {
this.azLogger.error(`[${envName}] ` + first, args);
} else {
this.azLogger.error(`[${envName}] ` + first);
}
}
public warn(...args: any[]): void {
const first = args.shift();
if (args.length > 0) {
this.azLogger.warn(`[${envName}] ` + first, args);
} else {
this.azLogger.warn(`[${envName}] ` + first);
}
}
public info(...args: any[]): void {
const first = args.shift();
if (args.length > 0) {
this.azLogger.info(`[${envName}] ` + first, args);
} else {
this.azLogger.info(`[${envName}] ` + first);
}
}
public verbose(...args: any[]): void {
const first = args.shift();
if (args.length > 0) {
this.azLogger.verbose(`[${envName}] ` + first, args);
} else {
this.azLogger.verbose(`[${envName}] ` + first);
}
}
}
MyLogger
in the AzureFunction http function and afterwards always use the custom logger for logging:const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const logger = new MyLogger(context.log);
logger.info('HTTP trigger function processed a request.');
...
}
traces
| order by timestamp desc
| parse message with '[' environment ']' msg
| extend TheMsg=iif(msg != '', msg, message)
| project timestamp, ENV=environment, OP=operation_Name, MSG=TheMsg
So without the need to use the "applicationinsights"
npm dependency and doing complicated configuration, the environment name is available as separate column in the logs.