Elastic Agent-prosessorer er kraftige, modulære komponenter som er designet for å manipulere og forbedre dataene på kildestadiet. Disse prosessorene tar inn et event, utfører en spesifisert handling – som parsing, filtrering, transformasjon eller berikelse – og sender deretter eventet videre. Når flere prosessorer er definert i en liste, utføres de i den angitte rekkefølgen. Denne sekvensielle utførelsen muliggjør en fleksibel, trinnvis datatransformasjon og berikelsesprosess som sørger for at dataene er optimalt forberedt for analyse, selv før de når innhentingsfasen.
Når man bruker Elastic Agent for å behandle dataene, er det viktig å merke seg at prosessorene opererer tidlig i dataarbeidsflyten. De utføres før eventuelle innhentingsrørledninger eller Logstash-behandling finner sted. Derfor kan prosessorkonfigurasjonene innen Elastic Agent ikke avhenge av eller referere til felter som er opprettet eller endret av senere stadier, som for eksempel innhentingspipelines eller Logstash.
For å sette opp en prosessor i Elastic Agent, kan man for eksempel gjøre følgende i Kibana: Gå til Management | Fleet | Agent Policies, finn policyen som kjører Apache-integrasjonen og klikk på "View Policy". Her kan du redigere integrasjonen, og under samlingen av Apache-loggfiler vil du finne feltet for Prosessorer, der du kan legge til ønsket kode for å berike dataene før de blir sendt videre til Elasticsearch. Eksempelet på kode kan være noe slikt som:
Når prosessorene er konfigurert og integrasjonen er lagret, vil de gjeldende endringene bli brukt på de kjørende Elastic Agents. Du kan deretter gå tilbake til Discover i Kibana for å se på de dokumentene som er sendt av agenten etter at prosessoren er lagt til.
Det er viktig å merke seg at prosessorene i Elastic Agent ikke har muligheten til å berike dataene fra Elasticsearch eller eksterne datakilder. Dette betyr at hvis du har behov for å hente inn data fra Elasticsearch eller andre systemer for å berike det som behandles av agenten, må du benytte en annen tilnærming, som for eksempel Logstash eller et eget script. Elastic Agent-prosessorene har heller ikke muligheten til å behandle data etter at de er normalisert til Elastic Common Schema, ettersom dette skjer i innhentingspipelines.
Tross disse begrensningene, er prosessorene fortsatt et nyttig verktøy i verktøykassen for databehandling innen Elastic Stack, spesielt for å filtrere ut hendelser tidlig i arbeidsflyten. Det er imidlertid viktig å forstå at ikke alle integrasjoner støtter prosessorer, og man bør alltid konsultere den offisielle dokumentasjonen fra Elastic for å bekrefte hvilke funksjoner som er tilgjengelige for hver integrasjon.
Elastic Agent-prosessorer er særlig verdifulle når det gjelder å filtrere bort uønsket data før det sendes til Elasticsearch, men det er også viktig å bruke dem med forsiktighet. Når du benytter integrasjonsbaserte innhentingspipelines, bør du være oppmerksom på at endringer i prosessorene kan fjerne eller modifisere felt som forventes av disse pipelinene, noe som kan føre til at de brytes.
Hvis du har behov for ytterligere funksjonalitet, som for eksempel mer avanserte transformasjoner, kan Script-prosessoren være en løsning. Denne prosessoren gir deg fleksibiliteten til å skrive egne Java-skript for spesifikke databehandlingsbehov.
For de som ønsker å bruke Logstash som en databehandler, tilbyr denne et alternativ til Elastic Agent-prosessorer, særlig når det er behov for mer kompleks databehandling. Logstash kan installeres på en Debian-basert maskin og brukes til å hente inn, prosessere og videresende data i sanntid ved hjelp av en pipeline-arkitektur. For å installere Logstash på et Debian-system, må man først legge til Elastic-repositoriet, deretter installere Logstash-pakken og kontrollere at den er riktig installert. Deretter kan man bruke Logstash for å konfigurere sine egne pipelines og filtere data på en mer tilpasset måte enn hva Elastic Agent-prosessorene tillater.
Det er også viktig å merke seg at Logstash kan integreres med Elastic Stack-komponentene som Elasticsearch og Kibana, og kan være et svært kraftig verktøy for databehandling og visualisering.
Endtext
Hvordan oppdage avvik i trafikkdata ved hjelp av maskinlæring
I arbeidet med å analysere trafikkdata, er det viktig å bruke effektive verktøy som kan identifisere avvik og anomalier i store datasett. I denne sammenhengen er Kibana et nyttig verktøy som kan hjelpe til med å oppdage avvik gjennom maskinlæring. Kibanas maskinlæring kan automatisk oppdage aggregeringer og verdier som kan benyttes for å lage jobber for anomalideteksjon, både for enkelt- og fler-metriske data.
For å opprette anomalideteksjonsjobber, begynner man med å bruke en visualisering i Kibana. For eksempel kan en fler-metrisk jobb opprettes ved å sette jobben til «rennes-traffic-status», der man i de ekstra innstillingene setter «Bucket span» til 1 time. Dette gir et overblikk over trafikkstatus, og Kibana vil kunne analysere variasjonene i dataene for å finne eventuelle unormale mønstre.
En enkelt-metrisk jobb, som for eksempel «rennes-traffic-average-speed», kan også opprettes ved å benytte «average_vehicle_speed»-feltet. Denne jobben fokuserer på hastigheten til kjøretøyene, og maskinlæringsmodellen vil automatisk identifisere eventuelle anomalier i trafikkmønsteret.
Når jobben er opprettet, kan resultatene vises i Kibanas Anomaly Explorer, der du vil kunne se avvikene i en swimlane-visning. Her blir de viktigste influensene på trafikkstatus og eventuelle unormale hendelser synlige. På samme måte kan enkelt-metriske resultater vises i en annen visning, der gjennomsnittet av kjøretøyhastigheten blir valgt som det viktigste måleparameteret.
Kibana lar deg også tilpasse disse jobbene etter opprettelsen. Du kan for eksempel endre dataspennet, sette opp varsler, og gjøre andre justeringer gjennom Kibanas grensesnitt for maskinlæring. Dette gjør det mulig å skreddersy analyseprosessene slik at de bedre møter spesifikke behov i datasettet ditt.
For å få best mulig nytte av Kibanas maskinlæringskapabiliteter, er det viktig å forstå at visuelle representasjoner av data må ha en tidsdimensjon for å kunne benyttes til anomalideteksjon. Det betyr at diagrammer som inneholder en dato- eller tidsakse, som linjediagrammer eller stolpediagrammer, er de mest relevante for maskinlæring.
I tillegg bør man være oppmerksom på at det er visse aggregasjonsfunksjoner som maskinlæring kan bruke for å oppdage anomalier. For eksempel kan gjennomsnitt, antall, maks, median, minimum, sum og unik_antal brukes til å finne avvik i dataene. Gjennom denne prosessen kan man oppdage skjulte mønstre i trafikkdataene som ellers ville vært vanskelig å oppdage manuelt.
Videre, når du oppretter jobber for anomalideteksjon, kan du dra nytte av Kibanas støtte for avanserte analysemetoder. Dette inkluderer ikke bare de enkle deteksjonsmetodene som nevnt ovenfor, men også mer avanserte maskinlæringsmodeller som benytter både tilsynte og ustyrede læringsmetoder. Disse kan brukes til å identifisere avvik i datasett med tidsstempler og til å analysere datastrukturer som kan være vanskeligere å analysere manuelt.
En annen viktig funksjon i Kibana er muligheten for å implementere data transformasjoner som pivot-tabeller for å omforme rådata til mer oversiktlige indekser som bedre kan brukes i maskinlæring. Denne tilnærmingen lar deg bryte ned dataene i mer håndterbare deler, slik at du kan analysere trafikkdata på ulike nivåer, for eksempel basert på tid på dagen eller ukedag.
Når vi ser på hvordan vi kan analysere og finne avvik i trafikkdata, er det flere faktorer som bør tas med i betraktning for å få en helhetlig forståelse av trafikkmønstre og anomalier. Den første er å vurdere hvilken type data du analyserer og hvilke metrikker som er mest relevante for det spesifikke formålet. For eksempel, hvis du fokuserer på kjøretøyhastighet, vil dette kreve en annen analysemetode enn hvis du ser på trafikkmengde eller kjøretøyens reisetid. I tillegg bør man ha en god forståelse for hvordan de ulike variablene i datasettet samhandler og hvordan disse kan endre seg over tid.
I videre analyser kan det være nyttig å bygge modeller for regresjon eller klassifisering, som kan forutsi fremtidige trafikkmønstre eller klassifisere bestemte hendelser som normale eller unormale. Dette kan være særlig verdifullt når du har tilgang til store mengder data og ønsker å automatisere identifikasjonen av anomalier i sanntid.
Kibanas integrasjon med tredjeparts NLP-modeller åpner også for muligheten til å analysere tekstdata som kan være relevante i trafikkprosessen, for eksempel trafikkinformasjon eller kommentarer fra brukere. Dette kan gi ytterligere innsikt som kan hjelpe til med å forstå de underliggende årsakene til trafikkavvikene.
Gjennom disse metodene kan vi utnytte kraften i maskinlæring til å avdekke skjulte mønstre og få dypere innsikt i trafikkdataene våre. Uansett om du jobber med sanntidsdata eller historiske data, gir Kibana et robust rammeverk for å utføre avanserte analyser og oppdage avvik på en systematisk og effektiv måte.
Hvordan fungerer implementeringen av semantisk søk med tette vektorer i Elasticsearch?
Implementeringen av semantisk søk i Elasticsearch krever en grundig forståelse av hvordan tette vektorer (dense vectors) brukes for å representere dokumentenes innhold på en måte som gjør at maskinlæringsmodeller kan tolke semantiske likheter, ikke bare tekstuelle treff. Det første viktige steget er å definere en egnet indekseringsmapping. I denne mappingen spesifiseres et nytt felt, for eksempel plot_vector, som får typen dense_vector med et fast antall dimensjoner — i eksemplet 384 dimensjoner — og en valgt likhetsfunksjon, ofte dot_product. Denne definisjonen forteller Elasticsearch hvordan det skal håndtere og sammenligne vektorene som representerer dokumentinnholdet.
Når indeksen er satt opp, opprettes en ingest pipeline som behandler hvert dokument før indeksering. Pipelines inkluderer ofte en inferensprosess hvor teksten fra et felt, som en plottbeskrivelse, sendes gjennom en maskinlæringsmodell — her en flerspråklig modell basert på Sentence Transformers. Modellen genererer en tettere vektorrepresentasjon som lagres i plot_vector-feltet. Etter at vektoren er hentet ut og kopiert til det endelige feltet, fjernes modellens rå outputdata for å holde dokumentene rene og konsise.
Bulk-innlesning av dokumenter foregår med en mindre chunk_size enn standard, ofte 100 i stedet for 500, for å unngå overbelastning ved beregningsintensive pipelines som denne. Prosessen rapporterer progresjon og antall vellykkede indekseringer, noe som er essensielt for å sikre datakvalitet og spore eventuelle feil.
Etter at dokumentene er indeksert, kan man visualisere og inspisere dem i Kibana. Det opprettes en ny datavisning som peker på den tette vektorindeksen, og det blir mulig å undersøke de vektoriserte feltene i individuelle dokumenter. Denne innsikten gir grunnlag for å teste søkefunksjonaliteten.
Selve semantiske søket utføres via en k-nærmeste nabo (kNN)-spørring, der søketeksten først konverteres til en tettere vektor gjennom samme maskinlæringsmodell som under indekseringen. Elasticsearch sammenligner deretter denne spørringsvektoren mot plot_vector-feltet i dokumentene, og returnerer de fem mest relevante dokumentene basert på vektoravstanden. Dette illustreres i en test hvor søket etter “romantic moment” gir treff på dokumenter som tematisk samsvarer med søketeksten, selv om ordlyden i teksten ikke matcher direkte. Det viser styrken i semantisk søk fremfor rent leksikalsk søk.
For å kunne sammenligne ytelsen og relevansen til semantisk søk med tradisjonelt leksikalsk søk, opprettes en søkeapplikasjon som bruker en BM25-basert tekstsøk-template. Dette gir en god kontrast og innsikt i hvordan ulike søkemetoder fungerer i praksis. Søkeapplikasjonen kan bygges videre for å inkludere avanserte filtre, sortering og aggregeringer, og danner dermed grunnlaget for en fullverdig søkeopplevelse.
Det er essensielt å forstå at bruk av tette vektorer for søk krever en nøye balansering mellom maskinlæringens muligheter og Elasticsearchs skalerbarhet og effektivitet. Valg av dimensjoner, likhetsmål og batch-størrelser ved bulk-innlasting påvirker både nøyaktighet og ytelse. I tillegg må modellen som genererer vektorene være godt tilpasset domenet for å sikre meningsfulle representasjoner. For å sikre høy kvalitet på søket er det viktig å validere både vektorene og resultatene i Kibana før implementasjon i en produksjonssetting.
Viktigheten av å kunne kombinere semantisk og leksikalsk søk kan ikke undervurderes, da brukersøk ofte vil ha behov for begge tilnærminger. Leksikalsk søk kan være mer presist for konkrete, veldefinerte søketermer, mens semantisk søk kan forstå nyanser og kontekst, og dermed gi treff som er tematisk relevante uten direkte tekstmatch. Å bygge søkeapplikasjoner som effektivt integrerer begge metoder gir derfor bedre brukeropplevelse.
Forståelsen av hele prosessen fra vektordefinisjon, inferenspipeline, bulk-innlasting, inspeksjon av data og til slutt søketesten, gir et solid fundament for å implementere avansert semantisk søk i Elasticsearch. Det legger til rette for videre utvikling av søkeløsninger som drar nytte av moderne maskinlæringsteknikker, samtidig som de beholder skalerbarheten og fleksibiliteten som Elasticsearch tilbyr.
Hvordan utvikle spørsmål-svar-applikasjoner med Generativ AI og Elasticsearch?
Å utvikle en applikasjon som benytter seg av generative språkmodeller og Elasticsearch kan åpne dørene for mer naturlige og effektive samhandlinger med data. I denne sammenhengen har vi et sett av verktøy og teknologier som kan hjelpe oss å bygge slike applikasjoner, deriblant LangChain, Elasticsearch, Ollama, og Streamlit.
LangChain er et kraftig rammeverk for å koble sammen språkmodeller med eksterne kunnskapskilder. Det gir oss en enkel måte å bygge komplekse applikasjoner som drar nytte av de generative mulighetene til språkmodeller samtidig som de integreres med strukturerte datakilder. Elasticsearch spiller en sentral rolle som søkemotor og datalager ved å tilby både vektor- og hybrid søk, som gjør at vi kan hente relevant informasjon raskt og effektivt. Ollama, som en lokal løsning for distribusjon av store språkmodeller (LLMs), gjør det mulig å kjøre LLMs direkte på vår maskin, noe som gir oss mer kontroll over databehandlingen. Streamlit, derimot, er verktøyet som gjør det mulig å bygge enkle og intuitive brukergrensesnitt på kort tid, noe som er ideelt for å lage interaktive applikasjoner.
En av de mest interessante tilnærmingene i dette prosjektet er bruken av RAG (Retrieval-Augmented Generation), som gir oss muligheten til å bruke de generative evnene til språkmodeller i kombinasjon med private og sensitive data som er lagret i Elasticsearch. Dette gjør at vi kan forbedre nøyaktigheten i svarene, samtidig som vi reduserer risikoen for feilaktig informasjon eller "hallusinasjoner" (feilaktige eller fabrikerte svar som språkmodellen kan produsere).
I det første eksemplet kan vi se hvordan vi kan bruke Ollama for å stille spørsmål til en LLM. Når vi spør om en film som handler om en kjærlighetshistorie og et verdifullt smykke ombord på et stort skip, får vi et svar som er uspesifisert og ikke helt presist, ettersom modellen ikke har tilgang til kontekstuell informasjon om filmen vi refererer til. Dette illustrerer begrensningen av språkmodeller når de ikke har tilgang til eksterne kilder.
Her kommer RAG-mønsteret inn i bildet. Ved å bruke Elasticsearch til å hente relevant informasjon om filmer fra vår datakilde, kan vi gi modellen tilgang til konteksten den trenger for å gi et korrekt og forventet svar. Ved å implementere et spørsmål-svar-system i applikasjonen, kan vi få svarene vi forventer, selv på spørsmål som refererer til filmer som ikke er allment kjente, men som finnes i vårt datasett. Dette er mulig fordi Elasticsearch fungerer som en "retriever" som henter relevante dokumenter basert på spørsmålet, og deretter gir denne informasjonen til LLM-en for å generere et presist svar.
Et annet eksempel på hvordan RAG kan benyttes er når vi spør modellen om en kommende film som kun er kjent for oss som forfattere. Uten tilgang til riktig informasjon fra en ekstern datakilde, kan modellen gi et usikkert svar. Men når vi spør gjennom applikasjonen som er koblet til Elasticsearch, får vi et umiddelbart og relevant svar fordi denne filmen er indeksert i vårt datasett. Dette demonstrerer hvordan RAG effektivt kan håndtere både offentlig og privat informasjon, og generere svar basert på begge.
Hvordan fungerer alt dette teknisk? I LangChain er det flere viktige komponenter som samarbeider for å bygge slike applikasjoner. Den viktigste er "retriever"-komponenten, som står for å hente relevant data til modellen. I vårt tilfelle er Elasticsearch den "retrieveren" som søker gjennom databasen og returnerer dokumenter som inneholder relevant informasjon basert på spørsmålet som stilles. Denne prosessen gjør det mulig for modellen å få tilgang til kontekstuell informasjon som den ellers ville hatt problemer med å generere på egen hånd.
Elasticsearch er konfigurert til å hente data basert på forskjellige søkestrategier, som f.eks. hybrid-søk, som kombinerer vektorbasert søk med tradisjonelt tekstbasert søk. Dette gjør det lettere for systemet å finne presis informasjon, selv i et stort datasett med ustrukturert tekst.
Når du utvikler en applikasjon som denne, er det flere elementer som er viktige å forstå. Først og fremst er det essensielt å forstå hvordan du kobler språkmodeller til datakilder på en effektiv måte. For det andre må du forstå hvordan du bruker Elasticsearch til å gjøre datainnhenting både rask og presis. Endelig er det viktig å forstå hvordan du kan bruke RAG til å kombinere generative språkmodellers evner med relevant informasjon fra datakilder for å oppnå mer nøyaktige og kontekstavhengige svar.
Med disse teknologiene på plass kan du utvikle applikasjoner som ikke bare besvarer spørsmål på en naturlig og interaktiv måte, men også gjør det på en måte som er kontekstuelt bevisst og nøyaktig. Dette er et skritt videre i utviklingen av intelligente systemer som kan håndtere både offentlig og privat data, og som kan gi svar som er både relevante og pålitelige.
Hvordan kan OpenTelemetry forbedre observabiliteten av applikasjoner?
I denne delen av boken skal vi se på hvordan tilpasset instrumentering og OpenTelemetry-støtte kan bidra til å forbedre overvåkingen og innsikten i applikasjoner, noe som gir en mer presis og helhetlig forståelse av både frontend og backend ytelse. Dette gir deg muligheten til å tilpasse observabilitetsstrategien din og tilpasse den til et stadig mer komplekst teknologilandskap.
Tilpasset instrumentering
I det opprinnelige eksempelet brukte vi auto-instrumentering levert av Elastic RUM-agenten. Dette kan imidlertid ikke alltid være tilstrekkelig, spesielt for single-page applications (SPA), der automatisk instrumentering av sideinnlastninger kanskje ikke gir nok innsikt. I slike tilfeller kan tilpasset instrumentering være en nyttig løsning. Denne metoden lar utviklere definere spesifikke transaksjoner og hendelser som de ønsker å overvåke, og gir mer detaljert innsikt i hvordan applikasjonen faktisk presterer på tvers av ulike scenarier.
For de som er interessert i å komme i gang med tilpasset instrumentering, finnes det konkrete eksempler og veiledninger tilgjengelig i den offisielle dokumentasjonen fra Elastic, som gir innsikt i hvordan man kan definere og implementere tilpassede transaksjoner.
OpenTelemetry-støtte
OpenTelemetry er et åpen kildekode-initiativ som gir et sett med API-er, biblioteker og verktøy for standardisert innsamling og håndtering av observabilitetsdata, inkludert målinger, logger og sporingsdata. Målet med OpenTelemetry er å gi utviklere en enhetlig løsning for å samle og analysere telemetridata fra applikasjoner på tvers av ulike plattformer og teknologier.
På tidspunktet for skrivearbeidet av dette kapittelet støttet OpenTelemetry instrumentering for RUM (Real User Monitoring), men det var ikke fullt integrert med Elastic sin Observability UI. Derfor ble et eksempel på Elastiflix-applikasjonen introdusert for å vise hvordan man kan instrumentere applikasjoner med Elastic APM-agenten og Elastic RUM JavaScript-agenten. Denne instrumenteringen lar Elastic Observability korrelere ytelsesdata fra frontend med innsikt fra backend-monitorering, og gir et mer komplett bilde av applikasjonens ytelse både på klient- og serversiden.
Integrering med Elastic Stack
OpenTelemetry tilbyr en svært fleksibel løsning som kan integreres med ulike observabilitetsbackends, og Elastic Stack er et av de mest brukte alternativene for slike integrasjoner. Ved å bruke OpenTelemetry som agent for å samle inn applikasjonsdata, kan du dra nytte av Elastic sin kraftige overvåkingsløsning for å visualisere, analysere og handle på dataene.
Når du bruker OpenTelemetry, kan du samle inn data fra flere observabilitetsdimensjoner som målinger, logger, profiler og syntetisk overvåking, og deretter bruke Elastic Stack for å få full oversikt over applikasjonens helse og ytelse. OpenTelemetry gir en standardisert måte å samle inn telemetridata på, som gjør det lettere å sammenligne og integrere data fra ulike applikasjoner og teknologier.
Hvordan instrumentere med OpenTelemetry
For å instrumentere applikasjonen din med OpenTelemetry, må du først sørge for at du har et operativt Kubernetes-kluster som møter de nødvendige kravene for å kunne kjøre OpenTelemetry-demoen. Dette inkluderer Kubernetes 1.24 eller høyere, 6 GB ledig RAM, og Helm 3.9 eller høyere. For denne demonstrasjonen bruker vi GKE (Google Kubernetes Engine) for å sette opp Kubernetes-klusteret, men det er også mulig å bruke andre Kubernetes-tjenester som Elastic Kubernetes Service (EKS) eller Azure Kubernetes Service (AKS).
Deretter er det nødvendig å sette opp Elastic Stack med APM-serveren aktivert og opprette et Kubernetes-secret med APM-serverens URL og hemmelig token, for å kunne sende data til Elastic Cloud. OpenTelemetry-agentene vil deretter samle inn og videresende sporingsdata, logger og målinger til Elastic Stack.
Verifisering og overvåking
Etter at du har satt opp og deployert OpenTelemetry-demoen på Kubernetes-klusteret, kan du bruke Kibana til å bekrefte at dataene blir sendt til Elastic Stack. Ved å gå til Observability > APM > Services i Kibana, og deretter se på "Service Map"-fanen, kan du bekrefte at observabilitetsdataene vises som forventet.
Demoapplikasjonen kan nå nås via en nettleser, og du vil kunne se data relatert til applikasjonens ytelse i sanntid. Dette gir deg innsikt i hvordan applikasjonen fungerer under ulike belastninger og scenarier, og lar deg raskt identifisere potensielle flaskehalser eller problemer i systemet.
Viktige betraktninger
Når du implementerer OpenTelemetry for observabilitet, er det flere ting å være oppmerksom på. Først og fremst er det viktig å forstå at mens OpenTelemetry tilbyr en standardisert tilnærming for innsamling av observabilitetsdata, krever det fortsatt at du velger de riktige verktøyene og tjenestene som passer best for dine spesifikke behov. OpenTelemetry er fleksibelt og tilpasningsdyktig, men det kan kreve ekstra konfigurasjon og finjustering, spesielt når det integreres med tredjepartsverktøy som Elastic Stack.
Videre er det viktig å merke seg at OpenTelemetry fortsatt er i utvikling, og det kan være utfordringer med å holde tritt med nye funksjoner og forbedringer. Dette betyr at man kan møte på situasjoner der visse funksjoner, som for eksempel full integrasjon med Elastic Observability, kan være i en tidlig fase av implementering.
Sist, men ikke minst, bør man vurdere hvordan observabilitetsdataene blir brukt. For å få mest mulig ut av OpenTelemetry og Elastic Stack, er det viktig å ha et klart mål for hva du ønsker å oppnå med dataene – om det er ytelsesanalyse, feilsporing eller systemoptimalisering. Å ha en gjennomtenkt strategi for hvordan dataene blir analysert og brukt, vil bidra til å få full verdi ut av systemet.
Hvordan håndtere feilsøking og problemer med meldingslevering i hendelsesdrevet arkitektur?
Hvordan digital bilder fungerer: Fra piksler til komprimering
Hvordan Shackleton overlevde den umulige ekspedisjonen: En lederskapshistorie

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский