Dit artikel verscheen oorspronkelijk op het Mews Ontwikkelaars blog.
Bij het schalen van onze technische organisatie vond de grootste dienst plaats bij ongeveer 20 ontwikkelaars. Daarvoor hadden we één tech-team dat alles regelde. Het enige onderscheid in dit team was naar functionaliteit: backend ontwikkelaars, frontend ontwikkelaars, enz. Verschillende functionaliteiten hadden verschillende methoden voor loggen, rapportage van fouten en prestatiebewaking. Sommige gereedschappen werden gedeeld, andere waren gespecialiseerd. Het beheer van deze stapel was echter vrij eenvoudig vanwege de eindige en vaste aard ervan. Met de transformatie naar meerdere cross-functionele teams (momenteel 13) gaat het niet meer alleen om het bouwen van de "machine" (het product), maar om het bouwen van een "machine" die "machines" bouwt (teams die producten bouwen).
Een groot onderdeel van deze "machine" van een hogere orde is het raamwerk voor incidentbeheer. Voor mij is het een van de indicatoren van de volwassenheid van een technische organisatie en het is een van mijn favoriete interviewvragen. Met incidenten bedoel ik alle onbehandelde uitzonderingen, fouten, uitval, prestatieproblemen, beveiligingsproblemen en wat er nog meer in je opkomt. Niet alleen direct in het product, maar ook in het omringende gereedschap. Net als veel andere bedrijven hadden we te maken met een aantal typische problemen:
- Niet alle incidenten vastleggen, er blind voor zijn en wachten tot gasten ze rapporteren.
- De incidenten vastleggen, maar ze om verschillende redenen negeren.
- Niet tijdig reageren op de incidenten, afhankelijk van de ernst ervan.
- Genereert veel valse positieven.
- Meerdere hulpmiddelen hebben om naar incidenten te zoeken.
- Niet genoeg data en inzicht hebben in hoe groot het probleem eigenlijk was.
In dit artikel beschrijf ik hoe we ons nieuwe incidentbeheerproces hebben ontworpen, al deze problemen hebben aangepakt en de technische oplossing hebben geïmplementeerd.
Vereisten
Bij het ontwerpen van de nieuwe workflow hebben we verschillende vereisten en beperkingen gedefinieerd op basis van onze eerdere ervaringen en problemen waar we mee te maken hebben gehad. Ons eerste doel was dat incidenten zeer gericht zouden worden aangeleverd, wat betekent dat problemen zouden worden aangeleverd aan de groep mensen die er hoogstwaarschijnlijk verantwoordelijk voor zijn en die de macht en kennis hebben om ze op te lossen. Als dit niet zou gebeuren, zou het omstandereffect optreden. Daarom moest voor elk incident het eigen team en de functie binnen het team worden gespecificeerd. Dat verkleinde de ontvangers van de hele organisatie tot een paar mensen.
Elk team zou één plek moeten hebben waar ze alle incidenten kunnen opzoeken.
De tweede belangrijke vereisten voor ons waren actie en traceerbaarheid. Eenvoudig gezegd wilden we niet dat de incidenten alleen maar vermeldingen waren in een logging platform, Slack notificaties of e-mails, omdat er geen garanties zijn dat iemand ernaar zou kijken of actie zou ondernemen. Je kunt niet gemakkelijk rapporteren over hun aantal, oplostijd of andere factoren, als sommige langer dan nodig onopgelost blijven, enz.
Tech-teamleider zijn is een van de moeilijkste functies, daarom wilden we de workflow voor incidenten heel gebruiksvriendelijk voor hen maken. Uiteindelijk zijn de tech-teams verantwoordelijk voor het oplossen van incidenten binnen hun teams. En omdat onze teams cross-functioneel zijn, wilden we niet dat de tech-teamleider veel verschillende tools moest doorlopen om een algemeen beeld te krijgen van wat er in hun teams gebeurt.
Opslag
Om actie en traceerbaarheid te garanderen, hebben we al vroeg besloten dat alle incidenten moeten worden doorgestuurd en opgeslagen in ons systeem voor probleemopsporing, YouTrack. De meeste incidenten zijn problemen die nog niet door een eindgebruiker zijn gerapporteerd, dus het heeft geen zin om ze gescheiden te houden van gerapporteerde fouten. We hebben ook vrij krachtige workflows, waarschuwingen en rapportage gebouwd bovenop YouTrack, dus die wilden we hergebruiken. Door incidenten daar bij te houden, krijgen we preciezere data over waar de teams tijd aan besteden. Bovendien gaat er niets verloren in de spam of wordt er niets over het hoofd gezien op Slack en ontwikkelaars hebben één plek om naar hun werkitems te zoeken. Al je incidenten doorsturen naar issue tracking software kan in het begin eng zijn, vooral als je er veel hebt, dus we raden een zachte uitrol aan, zodat teams wat tijd hebben om zich voor te bereiden op de toestroom.
Het zou echter niet slim zijn om alle incidenten rechtstreeks naar software voor het bijhouden van emissies te sturen, omdat er bijvoorbeeld geen tarieflimieten zijn. Daarom gebruiken we Sentry als een "gootsteen" voor alle incidenten die voor YouTrack staat en het beschermt tegen overstromingen. We maken vooral gebruik van de deduplicatie, tariefbeperking en waarschuwingsregels. Het heeft geen zin om elke keer dat dezelfde fout optreedt te rapporteren, net zo min als het zin heeft om de eerste keer dat een waarschuwing optreedt te rapporteren. Dit regelen we met waarschuwingsregels op basis van incidenttype (fout, waarschuwing, fataal), omgeving (productie, staging, ontwikkeling), aantal evenementen en andere criteria.
Opslag van incidenten in Sentry en escalatie naar de issue tracker.
Voor elke combinatie van team, functie en optioneel product is er een Sentry project. Je kunt eenvoudig kiezen voor welke projecten je interesse hebt, waardoor je kunt snijden op die dimensies en "weergaven" kunt aanmaken voor de teamleider (die alle projecten selecteert waarbij het team betrokken is) of de functieleider (die alle projecten selecteert, inclusief bijvoorbeeld frontend). De reden voor deze granulariteit is dat we daar ook implementaties en productversies bijhouden om te zien wanneer een implementatie een golf van fouten veroorzaakt. Sentry staat dit per project toe, wat ons dwingt om het te scheiden, ook al brengt dit wat operationele overhead met zich mee.
Collectie
Er zijn twee belangrijke bronnen van incidenten: onze applicaties en onze andere tools en systemen. Het verzamelen van incidenten uit onze applicaties is vrij eenvoudig. Sentry biedt SDK's voor de meeste platforms. Ons werk bestaat uit het bepalen van het team, de functionaliteit en het product van een incident. Functie en product zijn eenvoudig, omdat het duidelijk is in welke app het incident is ontstaan en welke functie ervoor verantwoordelijk is.
Verzamelen van incidenten uit verschillende bronnen.
Het team is lastiger, vooral als meerdere teams één applicatie onderhouden. We hebben een monolithische backend applicatie met de meeste teams die bijdragen, dus dit is iets wat we zeker moesten aanpakken :) Onze oplossing was om alle transacties in het systeem te annoteren met het eigen team op codeniveau. Dus wanneer code wordt uitgevoerd, is het duidelijk welk team de eigenaar is. Het eigenaarsteam kan gedefinieerd worden op grotere gebieden, bijvoorbeeld modules of hele API's, wat helpt bij het uitrollen van de eerste distributie van eigenaren. De teams rommelen dan in de loop van de tijd voortdurend met de toewijzingen, zodat het eigendom naar een stabiele toestand convergeert. Totdat een team weer wordt opgesplitst, natuurlijk.
Omweg 1: onze monolithische applicaties zijn eigenlijk behoorlijk modulair met een duidelijk eigenaarschap van elke regel uitvoerbare code. We proberen de beste aspecten van beide benaderingen te gebruiken: de eenvoud en prestaties van monolieten met het duidelijke eigenaarschap en de isolatie van microservices. Het transactionele eigenaarschap wordt niet alleen gebruikt voor incidenten, maar ook voor eigenaarschap van prestaties of grotere initiatieven voor refactoring als we vragen: "Wie moet dit eindpunt refactoren?".
De tweede categorie incidentproducenten zijn andere tools en systemen zoals New Relic, Azure Monitor, Azure DevOps, Rapid7 InsightOps, enz. Dergelijke tools ondersteunen meestal geen annotatie van de alerts met aangepaste metadata en daarom gebruiken we naamgevingsconventies om het team en andere attributen te onderscheiden. En omdat deze tools meestal niet rechtstreeks integreren met Sentry, routeren we webhooks door een geünificeerde "middleware" die is ingebouwd in Zapier die we gebruiken als een eenvoudige FaaS. Daar zetten we alle eigen webhookformaten om in één uniform formaat, extraheren we team, functie en product uit de waarschuwingsnaam en routeren we het incident naar Sentry.
Meldingen
Het laatste, makkelijkste, meest zichtbare (en voor sommige mensen het meest irritante) onderdeel is het meldingssysteem. Wanneer een probleem wordt aangekaart of geëscaleerd in onze software voor het bijhouden van problemen, wordt het opgepikt door een workflow en wordt er een webhook naar Zapier gestuurd. Daar distribueren we meldingen op basis van verschillende criteria naar verschillende kanalen. Altijd naar een Slack issue kanaal van het eigen team, soms naar een meer algemeen kanaal en, voor de ernstigste incidenten, naar PagerDuty.
Kennisgeving deel van de workflow.
Omweg 2: Het is je misschien opgevallen dat we Zapier veel gebruiken. Dat is geen toeval en zelfs als twee van onze tools een directe integratie hebben, routeren we de communicatie in plaats daarvan via Zapier. Dat stelt ons in staat om één plek te hebben waar we de communicatie tussen al onze systemen kunnen onderzoeken, wat enorm helpt bij het mogelijk debuggen van meer geavanceerde workflows. Niet alle tools hebben een goed inzicht in uitgaande webhooks, hun geschiedenis of waarom sommige zijn mislukt. Zapier heeft dat. Je kunt de payloads, de transformaties, de antwoorden van de ontvangers, enzovoort inspecteren. Het schrijven van een eenvoudige JavaScript-functie die wordt getriggerd door een webhook en een bepaalde actie uitvoert op basis van de binnenkomende data is een fluitje van een cent. Zapier kan worden gezien als een host, IDE en debugger voor dergelijke functionaliteit. Ik weet niet zeker of dit de oorspronkelijke bedoeling van de auteurs was, maar deze use case werkt erg goed voor ons.
Uitkomsten
We hebben al veel ideeën over wat we in elke stap van de workflow kunnen verbeteren. Van mooiere probleemomschrijvingen en slimmere en meer granulaire waarschuwingsregels tot betere meldingen met nog specifiekere ontvangers met escalatieregels en SLO's voor oplostijden. Maar zelfs zonder dergelijke extra's bracht de "basis" incident workflow verschillende voordelen voor onze organisatie:
- We hebben nu duidelijke, geconsolideerde en volledige data over onze incidenten, zodat we beslissingen kunnen nemen op basis van data.
- De manier waarop we fouten of onbehandelde uitzonderingen rapporteren wordt steeds beter, de teams ontdubbelen incidenten, onderdrukken fout-positieven en introduceren nieuwe incidenten die eerder werden genegeerd.
- Dankzij één bron van waarheid kunnen we snel zien of een team worstelt met een overvloed aan incidenten en hulp inschakelen.
- We hebben een veel beter inzicht in de kwaliteit van onze implementaties door incidenten ermee te correleren.
- De workflow is vooraf geconfigureerd voor alle teams en diensten en wordt geleverd als dienst van het platform. Het kost ongeveer 5 minuten wanneer een nieuw team wordt geïntroduceerd of een nieuwe naam krijgt.
- Het is gemakkelijk uit te breiden door nieuwe incidentverzamelaars te implementeren voor nieuwe tools in Zapier.
- Er gaat geen enkel incident "verloren in de vertaling", wat resulteert in een product van betere kwaliteit en snellere oplostijden, ter ondersteuning van onze visie om technische uitmuntendheid te bereiken.
Een helikopterview van de hele workflow.
Hopelijk geeft dit overzicht je wat inspiratie over wat je kunt verbeteren in je incidentmanagementproces. En andersom horen we graag wat jullie beter doen of wat we zouden kunnen verbeteren. Of, als je wilt dat ik dieper op een deel van het artikel inga, laat het me dan ook weten!
Escrito por

Honza Siroky
Honza is a Mews OG, having joined way back in 2012. He's now our Chief Technology Officer, heading up a team of 150+ developers, data scientists, QA and IT engineers.


