Update Maart 2024
Verschil tussen een dash en een hyphen
Deze maand heb ik het verschil tussen een dash en een hyphen geleerd. In beide gevallen is het "gewoon" een streepje maar de dash heeft spaties aan weerszijden van het streepje en de hyphen niet. De reden dat ik het geleerd heb is een probleem wat ik had met een azure pipeline en een secret wat begon met een streepje. Wij wilden een secret tijdens het runnen van de pipeline wegschrijven met het commando:
secret=$(az rest --method post --uri https://management.azure.com/subscriptions/{SomeLogicAppTriggerName} --query queries.sig --output tsv)
az keyvault secret set --vault-name SomeKeyvaultName --name SomeSecretName --value ${secret}
Dit secret
begon met een streepje. Hierdoor ging het commando om het secret te zetten verkeerd, de value leek leeg doordat het secret gezien werd als nieuwe parameter. Bij het zoeken naar een oplossing om het streepje te escapen of de waarde tussen quotes o.i.d. te zetten heb ik gezocht op de term dash. Dit leverde niet de juiste resultaten op.
Onderweg wel een aantal andere dingen geleerd wat je in bash kan doen zoals:
# tonen commando voor het uitgevoerd wordt
set -x
# Tonen van niet printbare tekens in een variabele
echo "$secret" | cat -v
# verwijderen van niet printbare tekens uit een variabele
secret=$(tr -dc '[[:print:]]' <<< "$secret")
Maar dit loste het probleem niet op. Het zoeken op secret starts with hyphen loste het probleem meteen op, de eerste hit bevatte de oplossing. Want wat bleek, je mag na de parameter naam ook een = zetten gevolgd door de waarde. Soms is het zo simpel.
secret==$(az rest --method post --uri https://management.azure.com/subscriptions/{SomeLogicAppTriggerName} --query queries.sig --output tsv)
az keyvault secret set --vault-name SomeKeyvaultName --name SomeSecretName --value=${secret}
zie het = na --value die alles heeft opgelost.....
OpenTelemetry via STDOut en STDerr
Loggen middels OpenTelemetry in een Kubernetes omgeving gaat makkelijker als gebruik gemaakt wordt van de standaard output en dan OpenTelemetry de files laten oppakken inplaats van de opentelemetry collector aanroepen vanuit de logging provider. Nog niet zelf geprobeerd, maar dat hoorde ik van een collega.
KQL subqueries
Om in een Azure workbook meerdere databronnen goed te kunnen combineren kan gebruik gemaakt worden van views. Daarvoor moet je gebruik maken van views. Die kan je dan met een union weer combineren.
Some other nice functions
- extend
> Create a new column
- summarize ... by
> groepeer resultaten (group by)
- countif
> alleen tellen als....
- minif
en maxif
> de min en max van een waarde als ze aan bepaalde voorwaarden voldoen
let flog = view () {
FunctionalLog
| where WorkflowName_s contains "workflow"
| extend WorkflowName=strcat(WorkflowName_s), ErrorMessage=strcat( Message), Run_id=strcat(RunId_s), Level=strcat(LogLevel_s), Code=""
| project TimeGenerated, WorkflowName, Level, Code, ErrorMessage,Run_id,AppName=tolower(LogicAppName_s)
};
let funcLog = view () {FunctionAppLogs
| where AppName contains "workflow" and FunctionName !=""
| where EventName contains "WorkflowTrigger" or Level == "Error" or Level == "Warning"
| extend WorkflowName=tostring(split(FunctionName, '.')[0])
| where WorkflowName contains "portability"};
union funcLog, flog
| summarize Started=countif(EventName =="WorkflowTriggerStart"), Ended=countif(EventName=="WorkflowTriggerEnd"), Errors=countif(Level=="Error"), LastError=maxif(TimeGenerated, Level=="Error" or Level=="Warning"), FirstError=minif(TimeGenerated, Level=="Error" or Level=="Warning"), LastRun=maxif(TimeGenerated,EventName=="WorkflowTriggerStart") by AppName, WorkflowName
| order by AppName, WorkflowName
Update Styling
Het was ook wel weer eens tijd om de styling van de site bij te werken. De kleuren zijn iets aangepast en op grote schermen wat meer van de ruimte gebruikt.
Ook heb ik een tagcloud toegevoegd. Allereerst met de penguin plugin tag_cloud
vervolgens het standaard theme aangepast door de resulterende tag_cloud op te nemen
<ul class="tagcloud">
{% for tag in tag_cloud %}
<li class="tag-{{ tag.1 }}">
<a href="{{ SITEURL }}/{{ tag.0.url }}">
{{ tag.0 }}
{% if TAG_CLOUD_BADGE %}
<span class="badge">{{ tag.2 }}</span>
{% endif %}
</a>
</li>
{% endfor %}
</ul>
Als laatste nog wat met de styling van de tag cloud waar ik mijn inspiratie heb gehaald uit: https://dev.to/alvaromontoro/create-a-tag-cloud-with-html-and-css-1e90 en https://css-tricks.com/create-a-tag-cloud-with-some-simple-css-and-even-simpler-javascript/
Ophalen input of output van logic app runs
Bij het runnen/checken van Logic apps is het soms lastig om iedere run open te klikken om de input en/of output van een stap te zien. Ik had laatst een geval dat ik veel runs door moest om de info van een bepaalde stap op te halen. Hier uiteindelijk maar een script voor geschreven.
Het script is nog niet perfect, het gaat er nog van uit dat er een bearer token uit de browser wordt gekopieerd, maar het begin is er. De logic app name, workflow en actie zijn al configureerbaar.
De stappen zijn eerst de runs ophalen, dan van iedere run de actie en in de actie zit een URL voor het ophalen van de input en output. In dit geval schrijf ik alles weg als XML, maar dat kan natuurlijk ook JSON zijn of gewoon text.
$bearerToken = "SOMETHING"
$logicAppName = "AppName";
$workflowName = "workflowname";
$subscriptionId = "subid";
$resourceGroup="workflowresourcegroup-rg";
$actionName = "action"
$RunsURL = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/$logicAppName/hostruntime/runtime/webhooks/workflow/api/management/workflows/$workflowName/runs/?api-version=2018-11-01&`$top=10"
$headers = @{
Authorization="Bearer $bearerToken"
}
# Get the logic app runs
#$responseRuns = Invoke-RestMethod -Uri $RunsURL -Method Get -Authentication Bearer -Token ($bearerToken | ConvertTo-SecureString -AsPlainText)
$responseRuns = Invoke-RestMethod -Uri $RunsURL -Method Get -Headers $headers
Write-Host($responseRuns)
foreach($run in $responseRuns.value)
{
Write-Host($run.name);
$runName = $run.name;
$runUrl = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/$logicAppName/hostruntime/runtime/webhooks/workflow/api/management/workflows/$workflowName/runs/$runName/actions/$actionName/?api-version=2018-11-01";
Write-Host($runUrl)
#$actionResult = Invoke-RestMethod -Uri $runUrl -Method Get -Authentication Bearer -Token ($bearerToken | ConvertTo-SecureString -AsPlainText);
$actionResult = Invoke-RestMethod -Uri $runUrl -Method Get -Headers $headers
$actionResultUri=$actionResult.properties.inputsLink.uri;
Write-host($actionResultUri)
#$actionResultXml = Invoke-RestMethod -Uri $actionResultUri -Method Get -Authentication Bearer -Token ($bearerToken | ConvertTo-SecureString -AsPlainText);
$actionResultXml = Invoke-RestMethod -Uri $actionResultUri -Method Get
new-item -Path "c:\temp\$runName.xml" -ItemType "file" -Value $actionResultXml.content
Write-Host "XML content saved to c:\temp\$runName.xml"
}