đŸ•”ïžâ€â™€ïž parselog.py

@mikkelrask · February 02, 2024 · 4 min read

Jeg havde én igennem pÄ mit arbejde, der oplevede at omtrent ~900 faktura havde fejlet i overfÞrslen fra Rackbeat til E-conomic.

Det er ikke unormalt at et API kald fejler eller bliver afvist, nÄr systemer taler sammen pÄ denne mÄde. Det ene system kan tillade X tegn i et bestemt felt, hvor det andet system kan tillade Y, osv. Men at finde hoved og hale i hvad der manglede pÄ NIHUNDREDE salg, selv med log-filerne/notifikationer vi har tilgÊngelige i Rackbeat, var det svÊr én lige at overskue.

Og yderligere - da fejlbeskederne ved afviste kald altid er fra kald-modtageren, er det ikke lige alle fejl som vi har fine "oversĂŠttelser" til. Det her var Ă©n af dem.

Fejlbeskederne var heldivis ensartede da alle faktura der havde fejlet, havde det en masse varer der var spÊrrede i E-conomic, men fortsat var salgsbare i Rackbeat. Da samtlige faktura der ikke indeholdte de spÊrrede varer fint var gÄet igennem, gik det Äbenbart under radaren at bilagene manglede i finansen, og hobede sig op til de fÞrnÊvnte, tÊt pÄ, 1000 salg over det seneste tre mÄneder.

Jeg kopierede al teksten fra log-siden, og da den kopierede data var i tabeller valgte jeg at indsÊtte det i mit Obsidian program, der er Markdown, sÄ jeg kunne bibeholde tabel-overblikket. Men nu sÄ det sÄdaledes ud:

|Faktura|Tidspunkt|Årsag|
|---|---|---|
|customer_invoice_key-4909|2024-02-14 19:11:21|{"message":"Validation failed. 1 error found.","errorCode":"E04300","developerHint":"Inspect validation errors and correct your request.","logId":"864e10e07f2da3a85-FRA","httpStatusCode":400,"errors":{"lines":{"items":[{"arrayIndex":8,"product":{"errors":[{"propertyName":"product","errorMessage":"Product 'SPE-16-029712-9000' is barred.","errorCode":"E06600","inputValue":"SPE-16-029712-9000","developerHint":"Find a list of products at https://restapi.e-conomic.com/products ."}]}}]}},"logTime":"2022-06-12T16:13:00","errorCount":1} :|
|customer_invoice_key-4596|2024-02-02 12:29:51|{"message":"Validation failed. 1 error found.","errorCode":"E04300","developerHint":"Inspect validation errors and correct your request.","logId":"90f9a932d6c19962-FRA","httpStatusCode":400,"errors":{"lines":{"items":[{"arrayIndex":0,"product":{"errors":[{"propertyName":"product","errorMessage":"Product 'SPE-16-029712-9000' is barred.","errorCode":"E06600","inputValue":"SPE-16-029712-9000","developerHint":"Find a list of products at https://restapi.e-conomic.com/products ."}]}}]}},"logTime":"2028-01-11T10:31:26","errorCount":1} :|
|customer_invoice_key-4523|2025-02-29 12:25:09|{"message":"Validation failed. 1 error found.","errorCode":"E04300","developerHint":"Inspect validation errors and correct your request.","logId":"90d910c454843628-FRA","httpStatusCode":400,"errors":{"lines":{"items":[{"arrayIndex":0,"product":{"errors":[{"propertyName":"product","errorMessage":"Product 'SPE-16-029719-9000' is barred.","errorCode":"E06600","inputValue":"SPE-16-029719-9000","developerHint":"Find a list of products at https://restapi.e-conomic.com/products ."}]}}]}},"logTime":"2023-02-19T11:26:47","errorCount":1} :|

.... etc (... data=faker.js for eksemplets skyld 🙄)

og som I kan se - stadig ikke det nemmeste at overskue, det det samme tabel og samme lange besked, men nu ogsÄ med link-data.

Python time

Co-pilot/Dall-E genererede denne illustration, ud fra det her indlĂŠg
Co-pilot/Dall-E genererede denne illustration, ud fra det her indlĂŠg
Men jeg skulle egentlig ogsÄ bare bruge det i et filformat, som jeg kunne parse programmatisk - for jeg ville nemlig takle det med et Python-script, der tog en hel fil som input, og kun gav den nÞdvendige information som kunden skulle bruge tilbage: Fakturanummeret der ikke var overfÞrt til finansen, og varenummeret der var spÊrret i e-conomic.

vi rackbeat-tools/parselog.đŸ”„

Jeg skyndte mig at Äbne neovim, og gÄ i krig! FremgangsmÄden var heldigvis simpel, netop da syntaksen var ens for bÄde fakturanummer og fejlbeskeder, sÄ kunne jeg bruge nogle regex patterns, hvor det var nemt at udvÊlge dét der varierede pÄ et findall-kald, og antage at dét var informationen der skulle bruges til at rette op pÄ det store rod.

import re #regex

with open("fejlbeskeder.md", "r") as file:
    content = file.read()

invoice_pattern = r"customer_invoice_key-(\d+)"

product_pattern = r"Product '([^']*)' is barred."

invoices = re.findall(invoice_pattern, content)
products = re.findall(product_pattern, content)

result = list(zip(invoices, products))

output_filename = "fejlbeskeder_parsed.md"
with open(output_filename, "w") as output_file:
    for invoice, product in result:
        output_file.write(f"Invoice: {invoice}\n")
        output_file.write(f"Barred Product: {product}\n\n")

print(f"Results have been saved to {output_filename}")

Og det gjorde at nÄr jeg kÞrer denne fil, at jeg fÄr et output der vises sÄledes i stedet:

Invoice: 4909
Barred Product: SPE-16-029712-9000

Invoice: 4909
Barred Product: SPE-16-029712-9001

Invoice: 4596
Barred Product: SPE-16-029719-9000

.....

Det var jo noget mere behageligt at se pÄ og viser nemt hvilke varer der har spÊrret for hvilken faktura!

Jeg kunne nok godt give det her lidt mere kÊrlighed, sÄ hvis det skal bruges en anden gang, at sÞrge for at kun lave ét instance for hver fejlet faktura, hvor, som I kan se jeg har taget med i mit eksempel, sÄ gÄr faktura-nummer 4909 igen to gange, da var flere fejl pÄ samme faktura.

SĂ„ mĂ„ske et output a la sĂ„dan noget her đŸ€·

Invoice: 4909
SPE-16-029712-9000
SPE-16-029712-9001

Invoice: 4596
SPE-16-029719-9000

Invoice: 4621
LKO-11-029559-8437

.....

Men vi fik hjulpet kunden i mĂ„l lynhurtigt, sĂ„ det ikke kun er deres finanslager der stemmer, men nu ogsĂ„ deres finans! đŸ€

Scriptet er jo meget niche, og meget specifikt, men det er tilgÊngelig som en del af rackbeat-tools (MIT), hvis andre har en uoverskuelig log der skal parses pÄ notifikations-siden - og kan nemt justeres til identificere andre fejlbeskeder, eller identificere flere forskellige typer fejl.

*Filen har ikke .đŸ”„ filformatet, som indlĂŠget indikerer. Det ser jo bare sejere ud.

@mikkelrask
ComputernĂžrden. Hobby futurist, linux entusiast, hardware hacker, tinkerer og generelt kreativt legebarn. Bosat i KĂžbenhavns Nordvest kvarter med min hund Homie. Jeg har arbejdet med computere hele mit liv, og ser en deres kunnen som en naturlig udvidelse af min egen.
© mr@github:~$ █, Built with Gatsby and hosted on Github.