Utilisez Function et Eventgrid pour réaliser une analyse et une conversion automatiques du journal de compte de stockage

Cet article est toujours l'idée précédente. Dans l'article précédent, nous avons partagé une idée. Vous pouvez télécharger le journal d'accès du compte de stockage via le script PowerShell, puis le télécharger automatiquement dans Log Analytics, afin qu'il puisse être directement dans LA Analysez et interrogez le journal. Bien que cette méthode soit simple et pratique, ce n'est pas une méthode automatisée après tout. Après avoir élargi nos idées, nous pourrions aussi bien essayer d'utiliser eventgrid combiné avec une fonction pour convertir cette méthode en une solution automatisée.

Commençons par vulgariser ce que sont EventGrid et Function

EventGrid

Avec Azure Event Grid, les applications peuvent être facilement générées à l'aide d'une architecture basée sur les événements. Tout d'abord, sélectionnez la ressource Azure à laquelle vous souhaitez vous abonner, puis fournissez un gestionnaire d'événements ou un point de terminaison WebHook auquel envoyer des événements. La grille d'événements inclut la prise en charge intégrée des événements des services Azure, tels que les objets blob de stockage et les groupes de ressources. La grille d'événements prend également en charge ses propres événements à l'aide de thèmes personnalisés.

En termes simples, c'est comme un déclencheur, qui peut déclencher divers événements, puis apporter des réponses ciblées. Cela ressemble un peu à des déclencheurs dans des applications logiques, mais eventgrid n'est qu'un simple outil de transfert d'événements, des méthodes de traitement en aval Complètement complété par d'autres produits, l'image suivante peut également être vue où se trouve la grille d'événements, similaire à une file d'attente de messages pour la transmission d'événements

https://docs.microsoft.com/en-us/azure/event-grid/?WT.mc_id=AZ-MVP-5001235

Image 1.png

Fonction

Azure Functions est une solution sans serveur qui permet aux utilisateurs de réduire l'écriture de code, de réduire l'infrastructure à entretenir et de réduire les coûts. Pas besoin de vous soucier du déploiement et de la maintenance des serveurs, l'infrastructure cloud fournit toutes les dernières ressources nécessaires pour maintenir les applications en cours d'exécution.

La fonction est en fait plus facile à comprendre. Désormais, tous les clouds ont fondamentalement des produits similaires. Si vous le comparez horizontalement, il s'agit d'AWS lambda, une plate-forme d'exécution de code entièrement gérée.

https://docs.microsoft.com/zh-cn/azure/azure-functions/functions-overview?WT.mc_id=AZ-MVP-5001235

En combinant la figure ci-dessus, nous pouvons réellement voir notre réflexion. Eventgird a des déclencheurs de blob intégrés, ce qui signifie que lorsqu'un nouveau blob apparaît, il déclenchera automatiquement la grille d'événements et les procédures de traitement en aval, nous pouvons combiner la fonction pour Faites, le code est en fait prêt à l'emploi, utilisez simplement le précédent, il a juste besoin d'être légèrement modifié, la charge de travail globale est très faible

Bien sûr, il y a en fait un problème caché ici, car le journal du compte de stockage est stocké dans le conteneur $ logs, et ce conteneur ne déclenchera pas la grille d'événements dans le backend Azure. C'est un peu délicat. La méthode que nous utilisons consiste à créer une fonction , Et puis utilisez azcopy pour synchroniser périodiquement la synchronisation des journaux avec un autre conteneur. Une seule ligne de code est facile, je ne l'écrirai donc pas pour le moment.

Étapes de mise en œuvre

Examinons les étapes d'implémentation spécifiques ci-dessous. Commencez par créer une application de fonction. La relation entre l'application de fonction et la fonction est très simple. L'application de fonction est équivalente à la plate-forme sur laquelle la fonction s'exécute. Le code s'exécute sur cette plate-forme. L'application de fonction peut en contenir plusieurs Fonction

Créer une application de fonction

Le processus de création d'une application de fonction est très simple, nous choisissons le runtime comme PowerShell Core

Image 2.png

Créer une fonction 

Une fois l'application Function créée, vous pouvez y créer des fonctions. Azure possède en fait une fonction de déclenchement de grille evenr intégrée, il vous suffit de la sélectionner lors de sa création.

Image 4.png


WeChat screenshot_20210112104638.png


Créer un abonnement Event Grid

La fonction est prête, alors vous pouvez préparer eventgrid, vous pouvez créer un abonnement à la grille d'événements directement dans la fonction

Image 5.png

Lors de la création d'un abonnement à une grille d'événements, de nombreux types peuvent être sélectionnés. Ici, veuillez choisir le type de stockage.

Image 6.png


Configurer le type d'événement du compte de stockage

Image 7.png


Faites ensuite attention à la nécessité de configurer le filtre, car nous devons limiter le chemin à une plage spécifique, tous les blobs ne déclencheront pas d'événements

Image 8.png

Le déclencheur est également prêt, puis vous pouvez préparer le code à traiter dans la fonction

Écrire le code

Étant donné que le code précédent est traité dans une boucle et que Eventgrid est en fait poussé un par un, la logique ici doit être légèrement ajustée

Fonction Build-Signature ($ customerId, $ sharedKey, $ date, $ contentLength, $ method, $ contentType, $ resource) 
{ 
    $ xHeaders = "x-ms-date:" + $ date 
    $ stringToHash = $ method + "` n "+ $ contentLength +" `n" + $ contentType + "` n "+ $ xHeaders +" `n" + $ resource 

    $ bytesToHash = [Text.Encoding] :: UTF8.GetBytes ($ stringToHash) 
    $ keyBytes = [Convertir ] :: FromBase64String ($ sharedKey) 

    $ sha256 = Nouvel objet System.Security.Cryptography.HMACSHA256 
    $ sha256.Key = $ keyBytes 
    $ calculéHash = $ sha256.ComputeHash ($ bytesToHash) 
    $ encodedHash = [Convert] :: ToBase64String ($ 
    calculéHash ) $ authentication = 'SharedKey {0}: {1}' -f $ customerId,$ encodedHash 
    retourne $ autorisation 
}

Fonction Post-LogAnalyticsData ($ customerId, $ sharedKey, $ body, $ logType) 
{ 

    

    $ method = "POST" 
    $ contentType = "application / json" 
    $ resource = "/ api / logs" 
    $ rfc1123date = [DateHeure] :: UtcNow .ToString ("r") 
    $ contentLength = $ body.Length 
    $ signature = Build-Signature ` 
        -customerId $ customerId` 
        -sharedKey $ sharedKey ` 
        -date $ rfc1123date` 
        -contentLength $ contentLength ` 
        -method $ method` 
        -contentType $ contentType ` 
        -resource $ resource 
    $ uri =" https: // "+ $ customerId +" .ods.opinsights.azure.com "+ $ resource +"? api-version = 01/04/2016 "
? api-version = 01/04/2016 " 
    $ headers = @ {
        "Autorisation" = $ signature; 
        "Log-Type" = $ logType; 
        "x-ms-date" = $ rfc1123date; 
        "champ généré par le temps" = $ TimeStampField; 
    } 

    $ response = Invoke-WebRequest -Uri $ uri -Method $ method -ContentType $ contentType -Headers $ headers -Body $ body -UseBasicParsing 
    return $ response.StatusCode 
} 

Fonction ConvertSemicolonToURLEncoding ([String] $ InputText) 
{ 
    $ ReturnText = "" 
    $ chars = $ InputText.ToCharArray () 



    $ StartConvert = $ false 



    foreach ($ c in $ chars) 
    { 
        if ($ c -eq '"') { 
            $ StartConvert =! $ StartConvert 
        }


        if ($ StartConvert -eq $ true -and $ c -eq ';') 
        { 
            $ ReturnText + = "% 3B" 
        } else { 
            $ ReturnText + = $ c 
        } 
    } 

    return $ ReturnText 
} 

Fonction FormalizeJsonValue ($ Text) 
{ 
    $ Text1 = "" 
    if ($ Text.IndexOf ("` "") -eq 0) {$ Text1 = $ Text} else {$ Text1 = "` "" + $ Text + "` ""} 
    if ($ Text1.IndexOf ("% 3B") -ge 0) { 
        $ ReturnText = $ Text1.Replace ("% 3B", ";") 
    } else { 
        $ ReturnText = $ Text1 
    } 
    return $ ReturnText 
} 

Fonction ConvertLogLineToJson ([String] $ logLine) 
{


    $ logLineEncoded = ConvertSemicolonToURLEncoding ($ logLine) 

    $ elements = $ logLineEncoded.split (';') 

    

    $ FormattedElements = New-Object System.Collections.ArrayList 
                
    foreach ($ element in $ elements) 
    { 

        $ NewText = FormalizeJsonValue ($ element) 
        $ FormattedElements .Add ($ NewText)> null 
    } 
    $ Columns =  
    ("version-number", 
        "request-start-time", 
        "operation-type", 
        "request-status", 
        "http-status-code", 
        "end to-end-latency-in-ms ", 
        " server-latency-in-ms ", 
        " authentication-type ",
        "nom-du-compte-demandeur",
        "nom-du-compte-propriétaire",
        "service-type", 
        "request-url ", "request- 
        object-key", 
        "request-id-header", 
        "operation-count", 
        "requester-ip-address", 
        "request-version-header", 
        "request-header-size", 
        "request-packet-size", 
        "response-header-size", 
        "response-packet-size", 
        "request-content-length", 
        "request-md5", 
        "server-md5 ", 
        " etag-identifier ", 
        " last-modified-time ", 
        " conditions-used ",
        "user-agent-header",  
        "referrer-header",
        "client-request-id" 
    ) 

    $ logJson = "[{";
    Pour ($ i = 0; $ i -lt $ Columns.Length; $ i ++) 
    { 
        $ logJson + = "` "" + $ Columns [$ i] + "` ":" + $ FormattedElements [$ i] 
        if ( $ i -lt $ Columns.Length - 1) { 
            $ logJson + = "," 
        } 
    } 
    $ logJson + = "}]"; 

    return $ logJson 
} 

$ storageAccount = Get-AzStorageAccount -ResourceGroupName $ ResourceGroup -Name $ StorageAccountName -ErrorAction SilentlyContinue 
if ($ null -eq $ storageAccount) 
{ 
    throw "Le compte de stockage spécifié n'existe pas dans cet abonnement." 
} 

$ storageContext = $ storageAccount.


$ maxReturn = 5000 
$ successPost = 0

$ subject = $ eventGridEvent.subject.ToString () 
$ BlobArray = $ subject.Split ('/') 
$ container = $ BlobArray [$ BlobArray.indexof ('containers') + 1] 
$ BlobIndex = $ subject.indexof (' blobs / ') + 6 
$ Blob = $ subject.substring ($ BlobIndex, $ subject.length - $ BlobIndex) 

Write-Output ("> Téléchargement du blob: {0}" -f $ blob) 
$ filename = ". \ log .txt " 
Get-AzStorageBlobContent -Context $ storageContext -Container $ container -Blob $ blob -Destination $ filename -Force> Null 
Write-Output ("> Publication de journaux dans le journal de l'espace de travail analytique: {0} "-f $ blob) 

$ lignes = Get-Content $ filename 

foreach ($ line in $ lines) 
        { 
            $ json = ConvertLogLineToJson ($ line)
           

            $ response = Post-LogAnalyticsData -customerId $ customerId -sharedKey $ sharedKey -body ([System.Text.Encoding] :: UTF8.GetBytes ($ json)) -logType $ logType 

            if ($ response -eq "200") { 
                $ successPost ++ 
            } else {  
                $ failedPost ++ 
                Write-Output "> Échec de la publication d'un journal dans l'espace de travail Log Analytics" 
            } 
        } 

        remove-item $ filename -Force 

    


Write-Output "> Lignes de journal publiées dans l'espace de travail Log Analytics: success = $ successPost, failure = $ failedPost "


La dernière étape consiste à autoriser l'application de fonction à accéder au stockage. Cette étape ne sera pas décrite en détail. Vous pouvez également utiliser la clé de compte de stockage pour le faire. Bien sûr, cette méthode n'est pas très recommandée.

Enfin, vous pouvez voir l'effet terminé dans le monitoring dans la fonction

Image 10.png

Pour résumer

De manière générale, cela n'a pas beaucoup changé par rapport à la manière d'utiliser simplement des scripts PowerShell, mais en raison de l'ajout de Eventgrid et de fonctions, la solution entière est devenue plus flexible. Des idées similaires peuvent également être étendues à de nombreuses autres tâches pour être davantage basées sur le cloud pour regarder et traiter les problèmes de manière native

Je suppose que tu aimes

Origine blog.51cto.com/mxyit/2588527
conseillé
Classement