Jak správně strukturovat adresáře v Azure Functions
- Základní adresářová struktura Azure Functions projektu
- Soubor host.json pro globální konfiguraci
- Soubor local.settings.json pro lokální vývoj
- Složka funkcí s jednotlivými function.json soubory
- Bindings a triggery v konfiguraci funkcí
- Shared code a společné knihovny
- Struktura pro různé programovací jazyky
- Deployment balíčky a jejich organizace
- Logs a monitoring v adresářové struktuře
- Extensions a závislosti v projektu
Základní adresářová struktura Azure Functions projektu
Adresářová struktura Azure Functions projektu je vlastně promyšlený systém, který vám pomáhá udržet pořádek ve všech souborech a složkách vaší serverless aplikace. Zkrátka a dobře – když s tím začínáte, může to vypadat trochu nepřehledně, ale jakmile pochopíte logiku, zjistíte, že vám to výrazně usnadní práci.
Představte si, že začínáte nový projekt. V kořenové složce vás čekají dva klíčové soubory, které budete potřebovat od samého začátku. Soubor host.json je takové velitelské centrum – tady nastavujete, jak se bude chovat celá vaše aplikace. Můžete si tu určit, jak dlouho může běžet jeden požadavek, jak podrobné chcete mít logování, nebo třeba kolik paměti může funkce využít. Není to nic složitého, ale rozhodně to má smysl nastavit pořádně hned na začátku. Vždyť nechcete, aby vám aplikace v produkci padala kvůli špatně nastaveným timeoutům, že?
Pak tu máme local.settings.json – a ten je trochu citlivější téma. Tady máte všechny hesla, přístupové klíče k databázím, API tokeny a podobné věci, které potřebujete při vývoji. Nikdy, ale opravdu nikdy tento soubor nenahrávejte na GitHub nebo jiný veřejný repozitář. To by bylo jako nechat klíče od bytu v zámku. Přidejte si ho hned do .gitignore a ušetříte si spoustu starostí. V produkci stejně používáte nastavení přímo v Azure portálu, takže místní soubor tam vůbec nepatří.
Každá funkce, kterou vytvoříte, dostane svůj vlastní domov – vlastní složku se svým jménem. Je to vlastně docela elegantní řešení. Když máte projekt s desítkami funkcí, oceníte, že se v tom dá vyznat. V každé takové složce najdete soubor function.json, kde je napsané, jak funkce funguje – na co reaguje, co přijímá a co vrací. Třeba když děláte funkci, která se spustí při nahrání souboru do úložiště, právě tady to nastavíte.
Dál narazíte na složky bin a obj. Pokud programujete v C# nebo Javě, bin obsahuje zkompilovanou aplikaci připravenou ke spuštění. Složka obj je zase plná dočasných souborů, které vznikají při kompilaci – ty vás vlastně vůbec nemusí zajímat a do gitu s nimi taky není třeba.
Pracujete s Node.js nebo Pythonem? Pak vám bude povědomá složka node_modules nebo venv. Správně nastavené závislosti jsou základ všeho – ovlivňují nejen to, jak rychle se vaše funkce spustí, ale i kolik místa zabere. A věřte mi, v cloudu se každý megabajt počítá, zejména když máte funkce, které se spouštějí tisíckrát denně.
Soubory jako requirements.txt nebo package.json jsou vlastně seznam nákupu pro vaši aplikaci. Tady píšete, jaké knihovny a v jakých verzích potřebujete. Díky tomu máte jistotu, že když nasadíte aplikaci do Azure, bude fungovat úplně stejně jako u vás na počítači. Už jste někdy zažili situaci, kdy vám kód fungoval lokálně, ale v produkci selhal? Často to bývá právě kvůli rozdílným verzím závislostí.
A co když máte kód, který používá víc funkcí najednou? Třeba nějaké pomocné funkce pro práci s daty nebo validaci vstupů? Právě k tomu slouží složka Shared nebo Common. Není nic horšího než kopírovat stejný kód na pět různých míst a pak při každé opravě chyby měnit všech pět verzí. Sdílený kód vám ušetří spoustu práce a hlavně nervů.
Soubor host.json pro globální konfiguraci
Když pracujete s Azure Functions, možná vás zpočátku překvapí, jak moc záleží na jednom malém souboru. Soubor host.json je totiž srdcem konfigurace celé vaší aplikace – najdete ho přímo v kořenovém adresáři projektu a řídí z něj chování všech funkcí najednou. Představte si ho jako dirigenta orchestru, který koordinuje všechny nástroje současně.
Co je na tom prakticky tak užitečné? Místo toho, abyste upravovali každou funkci zvlášť, nastavíte vše na jednom místě a máte klid. Je to trochu jako když si nastavíte hlavní ovladač teploty v celém domě – nemusíte běhat od radiátoru k radiátoru.
Soubor má klasickou JSON strukturu, nic složitého. Nejdřív si tady definujete verzi runtime, což je vlastně základ všeho. Bez správné verze by vám komponenty mohly začít dělat naschvály – trochu jako když se pokusíte spustit starou hru na novém počítači bez patřů.
Teď k něčemu, co vás v praxi zachrání nejednou – nastavení logování a diagnostiky. Tady si řeknete, co všechno chcete zaznamenávat, jak podrobné mají být logy a kam je poslat. Možná to zní nudně, ale když vám v produkci něco přestane fungovat ve tři ráno, budete rádi za každý záznam. Application Insights vám pak ukáže přesně, kde se to pokazilo.
Každý trigger má svá specifika a právě v host.json mu můžete říct, jak má pracovat. HTTP triggery potřebují vědět, kolik požadavků zvládnou najednou, jak dlouho mají čekat, nebo jak velkou vyrovnávací paměť použít. Pracujete s frontami? Nastavte si, kolik zpráv se má zpracovávat paralelně nebo co dělat, když něco selže. Je to jako když si v e-mailovém klientu nastavujete pravidla – jednou to uděláte a pak vám to šlape samo.
Výkon a škálování – tady se rozhoduje, jestli vaše aplikace pod zátěží poletí, nebo se zadrhne. Parametry jako maximální počet instancí nebo strategie škálování přímo ovlivňují, jak si aplikace poradí s návalem uživatelů. V produkci tohle není legrace – musíte najít tu správnou rovnováhu mezi výkonem a náklady. Nikdo nechce platit za desítky instancí, když běží naprázdno, ale zároveň nechcete, aby vám aplikace zkolabovala při Black Friday.
V adresářové struktuře leží host.json hned vedle složek s jednotlivými funkcemi. Tahle pozice vám hned napovídá – co tady nastavíte, platí pro všechny funkce bez výjimky. Je to mocný nástroj, ale vyžaduje trochu rozmyslu. Když něco změníte, ovlivní to celou aplikaci, takže si to dobře rozmyslete předem.
Chcete něco víc? Pokročilé konfigurace vám otevřou dveře ke specifickým nastavením pro Durable Functions, Event Hubs nebo Service Bus. Každé rozšíření má své vlastní možnosti a parametry, které můžete doladit podle svých potřeb. Dokumentace Azure vám k tomu řekne všechno potřebné.
Pozor na jednu věc – verze. Různé verze runtime podporují různá nastavení, takže když migrujete na novější verzi, počítejte s tím, že budete muset host.json upravit. Výchozí hodnoty se mění, přibývají nové možnosti, některé staré mizí. Není to nic hrozného, jen si před upgradem nastudujte, co se změnilo.
Soubor local.settings.json pro lokální vývoj
Když vyvíjíte Azure Functions na svém počítači, soubor local.settings.json je prostě nepostradatelný. Díky němu můžete pracovat s funkcemi lokálně, testovat je a ladit, aniž byste museli být pořád připojení k Azure cloudu. Najdete ho v hlavní složce vašeho projektu a ukrývá v sobě všechna klíčová nastavení a proměnné prostředí, která vaše aplikace potřebuje k životu.
Jak je tedy tento soubor uspořádaný? Je to vlastně docela logické. Nahoře máte vlastnost IsEncrypted, která říká, jestli jsou data uvnitř zašifrovaná. Pak přijde sekce Values, kde jsou uložené všechny proměnné prostředí a nastavení aplikace ve formátu klíč-hodnota. A teď pozor – tohle je důležité. Tento soubor je určený výlučně pro práci na vašem počítači. Nikdy, opravdu nikdy, byste ho neměli nahrávat do Gitu nebo ho sdílet veřejně. Proč? Protože v něm máte citlivé věci – připojovací řetězce, API klíče a podobně.
Jak vypadá typický projekt Azure Functions? Každá funkce má vlastní složku pojmenovanou podle ní. V té složce je soubor function.json, který definuje vazby a triggery. V hlavním adresáři pak máte host.json pro globální nastavení runtime prostředí a samozřejmě náš local.settings.json. Tahle struktura dává smysl a snadno se v ní orientujete.
Co rozhodně nesmíte zapomenout nastavit? Hodnotu AzureWebJobsStorage. Ta obsahuje připojovací řetězec k vašemu Storage účtu v Azure. Runtime Azure Functions ho používá pro svoje vnitřní potřeby – spravuje triggery, loguje průběh funkcí. Dobrou zprávou je, že pro lokální vývoj můžete klidně použít emulátor Azure Storage. Ušetříte si tím starosti se skutečným cloudovým úložištěm během testování.
Další věc, na kterou nesmíte zapomenout, je FUNCTIONS_WORKER_RUNTIME. Tady nastavujete, v jakém jazyce vaše funkce poběží – dotnet, node, python, java nebo powershell. Tohle je opravdu důležité pro zajištění kompatibility mezi vaším vývojovým prostředím a tím, co pak poběží v Azure.
Víte, co je super? Můžete si v local.settings.json definovat vlastní proměnné prostředí a pak je používat v kódu. To je přesně ten moderní přístup k vývoji – oddělit konfiguraci od kódu. A až budete nasazovat do Azure? Tam tyto hodnoty nahradíte skutečnými nastaveními přímo v Azure portálu.
Teď k bezpečnosti. Tohle není něco, co byste měli brát na lehkou váhu. Vždycky, ale opravdu vždycky, přidejte local.settings.json do .gitignore souboru. Chcete zabránit náhodnému prozrazení citlivých informací, že? Lepší je vytvořit vzorový soubor s nějakými obecnými hodnotami, který můžou ostatní v týmu použít jako šablonu.
Složka funkcí s jednotlivými function.json soubory
Když pracujete s Azure Functions, nejspíš znáte klasický způsob, jak si uspořádat kód. Každá funkce má vlastní složku a v ní soubor function.json. Možná to zní trochu staromódně, ale věřte, že tento osvědčený přístup se dodnes používá v nespočtu ostrých projektů a má své dobré důvody.
Představte si to jako bytový dům, kde má každý nájemník svůj byt. Podobně má každá funkce svůj vlastní prostor s jasně danými pravidly. Není to elegantní?
Jak to vlastně v praxi vypadá? V kořenové složce máte společné věci – soubory jako host.json nebo local.settings.json. A pak přijdou jednotlivé podsložky pro každou funkci. V každé takové složce najdete minimálně dva důležité soubory – function.json s nastavením a vlastní kód funkce, jehož název závisí na tom, jestli píšete třeba v C# nebo JavaScriptu.
Teď k tomu nejdůležitějšému kousku skládačky. Soubor function.json je srdce celé věci. Tady říkáte Azure, co má funkce dělat, na co má reagovat a kam posílat výsledky. Díky tomuto přístupu platforma přesně ví, jak se má vaše funkce chovat, aniž by musela luštit váš kód. A co je skvělé – tohle nastavení funguje stejně pro všechny jazyky.
Co z toho máte? Především klid. Konfigurace je oddělená od samotného kódu. Potřebujete změnit trigger nebo přidat vazbu? Žádný problém, sáhnete do function.json a hotovo. Tohle oceníte hlavně ve větších týmech, kde se třeba jedna skupina stará o infrastrukturu a druhá píše business logiku. Každá funkce je svůj samostatný svět, což zjednodušuje verzování i sledování změn.
Jedna praktická věc – dávejte pozor na názvy složek. Název složky se totiž stane identifikátorem funkce. Používá se v HTTP adresách i při sledování běhu aplikace. Chcete přece vědět, která funkce zrovna běží nebo spadla, že?
Největší výhoda? Flexibilita pro každou funkci zvlášť. Jedna funkce potřebuje delší timeout, druhá jiná oprávnění? V pohodě, každá má svoje nastavení. To se hodí, když máte rozmanitější aplikaci s různými požadavky.
A co když chcete přidat novou funkci? Nic jednoduššího. Vytvoříte novou složku, hodíte tam function.json a soubor s kódem, a při příštím nasazení se Azure o zbytek postará samo. Vaše aplikace může růst postupně, bez toho, abyste museli všechno přepisovat od základu.
Bindings a triggery v konfiguraci funkcí
Když pracujete s Azure Functions, narazíte na dva základní prvky, které určují, jak vaše funkce komunikují se světem kolem nich – bindings a triggery. Celá tahle magie se řídí prostřednictvím souboru function.json, který najdete v adresáři každé funkce. Tento konfigurák vlastně říká, co má funkce dělat a jak má reagovat na různé události.
Trigger je to, co vaši funkci probudí k životu. Je to vlastně spouštěč, který řekne: Teď je čas začít pracovat! A tady platí jedno důležité pravidlo – každá funkce musí mít právě jeden trigger, ani víc, ani míň. Představte si třeba HTTP trigger, který reaguje, když někdo pošle HTTP požadavek. Nebo timer trigger, který spustí funkci podle časového plánu – třeba každý den ve tři ráno. A pak tu máme queue trigger, který se aktivuje, když do fronty v Azure Storage dorazí nová zpráva. V tom function.json souboru najdete trigger v sekci bindings, kde má direction nastavené na in a type, který říká, o jaký druh triggeru jde.
Bindings, tedy vazby, jsou pak způsob, jak propojit funkci s externími zdroji dat bez zbytečného kódování. Prostě jim řeknete, odkud chcete data číst a kam je zapisovat, a ono to funguje. Nemusíte se trápit s připojováním, autentizací a dalšími technickými detaily. Máme dva základní typy – vstupní bindings (direction in) pro čtení dat a výstupní bindings (direction out) pro zápis. Tohle vám ušetří spoustu času a starostí.
Pokud se podíváte na strukturu Azure Functions, každá funkce si žije ve vlastním adresáři se všemi svými soubory. Najdete tam ten zmíněný function.json s kompletní konfigurací a samozřejmě samotný kód funkce. A ten můžete napsat v jazyce, který vám vyhovuje – C#, JavaScript, Python, Java nebo PowerShell.
Ten function.json je v JSON formátu a obsahuje pole bindings, kde jsou všechny vazby včetně triggeru. Každý binding potřebuje pár základních věcí – type (jaký typ vazby to je), direction (kterým směrem data tečou) a name (jak se k těm datům dostanete v kódu).
Když třeba nastavujete HTTP trigger, určíte, jaké HTTP metody funkce přijímá a jakou autorizaci vyžadujete. U queue triggeru zase zadáte název fronty a connection string pro propojení s úložištěm. Výstupní bindings pak můžou posílat data kamkoliv potřebujete – do databází, front zpráv, blob storage nebo dalších Azure služeb. A všechno tohle nastavíte v jediném souboru.
Krása celého řešení spočívá v tom, že máte konfiguraci oddělenou od kódu. Díky tomu můžete snadno měnit vazby bez toho, abyste museli šahat do samotné implementace. Azure Functions runtime se pak o všechno postará sám – spravuje připojení, stará se o jejich životní cyklus a když něco selže, automaticky to zkouší znovu.
Adresářová struktura Azure Functions představuje fundament organizace kódu, kde každá funkce žije ve vlastním izolovaném prostoru s jasně definovanými vstupy a výstupy, což umožňuje vývojářům budovat škálovatelné aplikace s minimální režií na správu infrastruktury.
Radovan Kubíček
Shared code a společné knihovny
Když budujete aplikace v Azure Functions, brzy narazíte na situaci, kdy potřebujete použít stejný kus kódu na více místech. Představte si, že máte deset různých funkcí a všechny potřebují validovat emailové adresy nebo formátovat data stejným způsobem. Kopírovat tentýž kód do každé funkce? To by byla noční můra při jakékoli změně.
Místo toho můžete vytvořit centrální místo pro sdílený kód, ke kterému mají všechny vaše funkce přístup. Funguje to podobně jako domácí knihovna – místo abyste si kupovali stejnou knihu desetkrát, máte ji jednou a všichni z rodiny si ji můžou půjčit.
Jak na to prakticky? Nejjednodušší způsob je vytvořit speciální složku přímo v projektu. Můžete ji pojmenovat třeba shared, common nebo jak se vám líbí. Není to věda – hlavně ať to dává smysl vám a vašemu týmu.
Teď záleží na tom, v čem programujete. Pokud používáte Node.js, stačí ve sdílené složce vytvořit běžné JavaScript nebo TypeScript soubory a importovat je pomocí relativních cest. Je to stejné, jako když importujete jakýkoliv jiný modul – akorát míříte do své vlastní složky místo do node_modules.
V C# a .NET světě to funguje trochu jinak, ale princip zůstává stejný. Využijete namespace a using direktivy a můžete si organizovat sdílené třídy a metody do přehledné struktury. Když projekt roste, dává smysl vytvořit dokonce samostatnou Class Library a tu pak referencovat. Dostanete tím bonusem silnou typovou kontrolu a Visual Studio vám pomůže s refaktoringem.
Python nabízí elegantní řešení přes balíčky. Stačí do složky přidat soubor __init__.py a máte importovatelný balíček. Jednoduché a dodržuje to princip DRY – Don't Repeat Yourself, což je v podstatě zlaté pravidlo každého programátora.
Ale pozor – nestačí jen hodit všechno do jedné složky a doufat v nejlepší. Musíte nad tím trochu přemýšlet. Validační logika patří jinam než transformace dat, a pomocné funkce pro API zase někam úplně jinam. Čím lépe si to rozčleníte do modulů, tím snazší bude později cokoliv najít nebo otestovat.
Co když máte víc projektů, které potřebují stejný sdílený kód? Tady se vyplatí jít o level výš a vytvořit si vlastní balíček – ať už NuGet, npm nebo Python wheel. Ano, je to víc práce na začátku, ale získáte tím přesnou kontrolu nad verzemi a distribucí kódu napříč projekty. Žádné u mě to fungovalo problémy.
A ještě jedna věc, na kterou nesmíte zapomenout – výkon. Azure Functions vás účtují podle toho, jak dlouho běží a kolik zdrojů spotřebují. Pokud váš sdílený kód zbytečně zpomaluje inicializaci nebo zpracování požadavků, platíte za to. Takže si dejte pozor, aby byl kód optimalizovaný. Někdy stačí načíst věci až když je skutečně potřebujete, místo abyste je všechny inicializovali hned na začátku.
Sdílený kód v Azure Functions není rocket science, ale chce to trochu plánování a zdravý rozum. Když to uděláte správně, ušetříte si spoustu času a hlavně nervů při údržbě aplikace.
Struktura pro různé programovací jazyky
Adresářová struktura Azure Functions vypadá úplně jinak podle toho, jaký programovací jazyk si vyberete. Každý jazyk má prostě svoje zvyklosti a způsob, jak organizovat soubory – a to není náhoda, ale odráží to, jak se v daném ekosystému běžně pracuje.
Když stavíte funkce v C# a .NET, najdete strukturu, která vám bude povědomá z klasických .NET projektů. Máte tam csproj soubor, který drží pohromadě všechny závislosti a nastavení projektu. Každá funkce je pak vlastně třída s metodou, která má atribut FunctionName – jednoduché a přehledné. Konfigurace běží přes host.json a pro lokální vývoj používáte local.settings.json. Většinou si vývojáři vytváří složky podle kategorií funkcí, aby se v tom lépe orientovali. A kam se kompiluje výsledný kód? Do složky bin, jak jste zvyklí z celého .NET světa.
S JavaScriptem nebo TypeScriptem je to trochu jiná písnička. Tady má každá funkce svůj vlastní adresář se dvěma základními soubory: index.js (nebo index.ts) s kódem a function.json s nastavením triggerů a vazeb. V kořenu projektu najdete package.json, kde jsou všechny Node.js závislosti a skripty pro spuštění. Pokud používáte TypeScript, přibude ještě tsconfig.json pro nastavení transpilace. Zkušení vývojáři si často vytváří složky jako lib nebo utils, kam dávají pomocné funkce – kód je pak čitelnější a dá se lépe znovu použít.
U Pythonu struktura respektuje pythonové zvyklosti pro práci s moduly. Každá funkce má svůj adresář s __init__.py souborem, kde je samotný kód, a function.json s konfigurací. V kořenu projektu máte requirements.txt se seznamem závislostí a obvykle taky virtuální prostředí ve složce .venv nebo venv. Často narazíte i na složku shared, kam se dává kód sdílený mezi funkcemi – šetří to čas a udržuje projekt přehledný.
Java projekty stojí na Maven nebo Gradle build systémech. Klasická Maven struktura znamená src/main/java pro zdrojáky a pom.xml, kde definujete projekt a jeho závislosti. Funkce píšete jako metody v Java třídách s Azure Functions anotacemi. Po kompilaci skončí všechno v target adresáři jako JAR soubor připravený k nasazení.
PowerShell funkce mají podobný přístup jako JavaScript – každá funkce ve vlastní složce s run.ps1 skriptem a function.json konfigurací. Pokud potřebujete společné nastavení pro všechny funkce, použijete profile.ps1 v kořenu projektu.
Zajímavé je, že bez ohledu na to, jestli píšete v C#, Pythonu nebo čemkoliv jiném, některé věci zůstávají stejné. Všechny projekty mají host.json pro globální konfiguraci runtime prostředí a local.settings.json pro lokální vývoj. Díky tomu se aplikace chovají konzistentně napříč jazyky a máte centrální místo pro správu nastavení.
Deployment balíčky a jejich organizace
Deployment balíčky jsou základním kamenem práce s Azure Functions a jejich správné nastavení vám může ušetřit spoustu času i problémů. Možná jste už zažili situaci, kdy jste něco nasadili do produkce a najednou to nefungovalo, přestože lokálně všechno běželo bez problémů. Často právě za tím stojí špatně sestavený deployment balíček.
| Složka/Soubor | Popis | Povinnost |
|---|---|---|
| host.json | Globální konfigurační soubor pro celou aplikaci funkcí | Povinný |
| local.settings.json | Lokální nastavení a proměnné prostředí pro vývoj | Volitelný (pouze lokálně) |
| function.json | Konfigurace jednotlivé funkce (triggery, bindings) | Povinný pro každou funkci |
| __init__.py | Hlavní soubor s kódem funkce (Python) | Povinný pro Python funkce |
| index.js | Hlavní soubor s kódem funkce (JavaScript/Node.js) | Povinný pro Node.js funkce |
| run.csx | Hlavní soubor s kódem funkce (C# Script) | Povinný pro C# Script funkce |
| requirements.txt | Seznam závislostí pro Python projekty | Volitelný (Python) |
| package.json | Seznam závislostí pro Node.js projekty | Volitelný (Node.js) |
Jak to vlastně celé funguje? Představte si, že balíte kufr na dovolenou – musíte do něj dát všechno podstatné, co budete potřebovat. Podobně je to s deployment balíčkem. Zabalíte do něj zkompilovaný kód, konfigurační soubory, všechny knihovny a další věci, bez kterých vaše funkce prostě nepoběží. A stejně jako u toho kufru – pokud něco důležitého zapomenete nebo naopak přebalíte zbytečnostmi, budete mít problém.
Co se týče struktury, není to úplně totéž jako váš zdrojový kód. Během sestavení se totiž dějí různé věci – TypeScript se překládá do JavaScriptu, C# kód se kompiluje, knihovny se kopírují na správná místa. V kořenu balíčku vždycky najdete host.json, což je takový hlavní konfigurační soubor pro celou aplikaci, a pak jednotlivé složky pro každou funkci zvlášť.
Zajímavé je, že to vypadá jinak podle toho, v čem programujete. Když používáte C#, máte tam hlavně DLL soubory. S JavaScriptem nebo Pythonem tam budou zdrojové soubory a nainstalované balíčky z npm nebo pip. Velikost těch externích závislostí pak dokáže pořádně ovlivnit, jak rychle se vaše aplikace nasadí a jak dlouho trvá její start.
Tady přichází důležitá věc – optimalizace. Nikdo nechce čekat věčnost, než se aplikace nasadí, že? Proto je dobré vyhodit všechno, co tam opravdu nemusí být. Vývojové nástroje, testy, různé pomocné soubory – to všechno ven. Pomocí funkce jako funcignore soubor si můžete přesně říct, co chcete zahrnout a co ne, podobně jako funguje .gitignore.
Dneska se hodně používají i Docker kontejnery. To je trošku jiná liga – zabalíte si celou funkci včetně prostředí do obrazu. Máte pak větší kontrolu, ale taky to vyžaduje trochu jiný přístup. Hodí se to hlavně když máte komplikovanější závislosti nebo potřebujete mít úplně stejné prostředí všude.
A pak je tu ještě otázka různých prostředí. Produkce, testovací prostředí, vývojové prostředí – každé může potřebovat trochu jinou konfiguraci. Naštěstí nemusíte vytvářet samostatný balíček pro každé z nich. Díky application settings v Azure můžete mít jeden balíček, který se sám přizpůsobí tomu, kam ho nasadíte. To vám ušetří spoustu práce a hlavně snižuje riziko, že se někde něco pokazí kvůli rozdílům mezi balíčky.
Logs a monitoring v adresářové struktuře
Když pracujete s Azure Functions, zjistíte, že správné nakládání s logy a monitorováním není jen technická formalita – může vám ušetřit hodiny frustrace při hledání chyb. Představte si situaci: vaše aplikace přestane v produkci fungovat a vy nemáte tušení, kde začít hledat problém. Znáte to?
Logy a monitorovací data se v Azure Functions ukládají do několika klíčových míst, která byste měli znát nazpaměť. Základem je adresář LogFiles v kořenové složce vaší aplikace. Najdete tam aplikační logy, záznamy HTTP požadavků i detailní trasovací informace. Vše hezky uspořádané podle typu a času, takže když něco hledáte, nemusíte se probírat celým archivem.
Application Insights je váš nejlepší kamarád pro monitoring Azure Functions. Jeho konfigurace žije v souborech projektu – konkrétně instrumentační klíč najdete v local.settings.json při lokálním vývoji a v nastavení aplikace pro produkci. Díky němu vidíte výkon funkcí, zachytáváte výjimky, sledujete závislosti a vlastní metriky. Zkrátka všechno, co potřebujete k tomu, abyste měli přehled o tom, co se ve vaší aplikaci děje.
Soubor host.json je další kritický kousek puzzle. Právě tady nastavujete, jak se má celá funkční aplikace chovat ohledně logování. Můžete definovat úrovně logování pro různé kategorie, nastavit vzorkování telemetrie a doladit další aspekty monitoringu. Dobře nastavený host.json znamená, že máte dost informací na diagnostiku, ale nezahltíte systém zbytečnými daty.
Když vyvíjíte lokálně, logy putují do konzole a do místního adresáře. Azure Functions Core Tools vám ukážou v reálném čase, co se děje – vstupní parametry, výstupy, chyby. To všechno vidíte okamžitě, což výrazně zrychluje ladění. Pamatujete si, kdy jste naposledy strávili půlku dne hledáním chyby, která by se s pořádnými logy našla za minutu?
V produkci je struktura logů samozřejmě složitější. K vaší funkční aplikaci je připojený Azure Storage účet se speciálními kontejnery. Kontejner azure-webjobs-hosts uchovává metadata o běhu funkcí, azure-webjobs-secrets pak šifrované klíče a citlivé údaje. O tyto kontejnery se stará Azure Functions runtime automaticky, což je určitě plus.
Monitoring zahrnuje i soubory pro sledování zdraví aplikace. V host.json můžete nakonfigurovat health check endpointy, které pravidelně kontrolují, jestli všechno funguje, jak má. Tyto kontroly generují vlastní logy uložené mezi ostatními diagnostickými daty.
Pro náročnější scénáře si můžete vytvořit vlastní logovací poskytovatele. Jejich konfigurace a závislosti uložíte do příslušných adresářů projektu. Třeba když potřebujete propojení s externími systémy pro správu logů nebo specializované nástroje pro analýzu výkonu. Konfigurace těchto poskytovatelů obvykle sídlí v konfiguračních souborech nebo v dependency injection kontejneru.
Nezapomínejte ani na retenci a rotaci logů – bez správného nastavení vám můžou logy sežrat úložiště rychleji, než čekáte. Azure Functions sice některé typy logů rotuje automaticky, ale pro specifické potřeby si můžete vytvořit vlastní mechanismy pomocí triggers a bindings. Je to jako s domácím úklidem – když se o to nestaráte pravidelně, nakonec to na vás dolehne najednou.
Extensions a závislosti v projektu
# Rozšíření a závislosti v Azure Functions
Když pracujete s Azure Functions, brzy narazíte na důležitou věc – rozšíření a jejich správu. Možná vás překvapí, jak moc ovlivňují to, co ve svých funkcích dokážete dělat. Rozšíření jsou tím, co definuje vaše možnosti – určují, jaké triggery můžete použít a jak propojíte své funkce s dalšími službami.
Pojďme se podívat, kde se tyhle věci vlastně schovávají. Ve vašem projektu najdete extensions.csproj nebo host.json – soubory, které vypadají nenápadně, ale dělají hodně práce. Ten první obsahuje odkazy na NuGet balíčky. Představte si to jako nákupní seznam funkcionalit. Chcete zpracovávat zprávy z Azure Storage Queue? Pak potřebujete Microsoft.Azure.WebJobs.Extensions.Storage. Bez něj to prostě nepůjde.
Se závislostmi se pracuje úplně standardně přes NuGet, jak to znáte z běžného .NET vývoje. Každé rozšíření je samostatná závislost a musíte ji v projektu explicitně uvést. Když vytváříte nový projekt, nějaká základní rozšíření se nainstalují automaticky – to je fajn. Ale jak rostou vaše ambice, přidáváte další a další balíčky.
Teď pozor na jednu záludnost – verzování. Azure Functions runtime má několik verzí a každá si rozumí jenom s určitými verzemi rozšíření. Musíte hlídat, aby k sobě runtime a rozšíření pasovaly, jinak vás čekají nepříjemná překvapení při nasazení. V host.json můžete nastavit verzi extension bundle – to je taková předpřipravená sada rozšíření, která vám ušetří spoustu starostí se správou.
Jak to funguje, když vyvíjíte na svém počítači? Vlastně docela příjemně. Když poprvé spustíte projekt, Azure Functions Core Tools se podívají, co používáte, a potřebná rozšíření si stáhnou samy. Většinou si toho ani nevšimnete. Ale stojí za to vědět, co se tam děje pod pokličkou – ušetří vám to čas při řešení problémů.
V produkci na Azure je situace trochu jiná. Používáte-li extension bundles, Azure vám rozšíření dodá automaticky. Nemusíte je zahrnovat do nasazovaného balíčku, což znamená menší velikost a rychlejší deployment. Někdy ale potřebujete přesnou kontrolu nad verzemi – pak rozšíření zahrnete přímo do projektu. Je to víc práce, ale máte jistotu, že běží přesně to, co chcete.
V souboru host.json se dá nakonfigurovat spousta věcí. Třeba kolik zpráv z fronty se má zpracovávat najednou, nebo jak se má systém chovat při chybách. Tahle nastavení platí pro všechny funkce v jedné Function App, takže si to dobře rozmyslete.
A co aktualizace? Tady opatrně. Nová verze rozšíření může přinést změny, které rozbijí to, co doteď fungovaló. Proto nejdřív testujte v bezpečném prostředí, než cokoli nasadíte do produkce. Verzování a pořádný CI/CD proces vám zachrání život – nebo aspoň pár bezesných nocí.
Publikováno: 20. 05. 2026
Kategorie: Cloudové služby