Este artículo sigue siendo la idea anterior. En el artículo anterior, compartimos una idea. Puede descargar el registro de acceso de la cuenta de almacenamiento a través del script de PowerShell y luego cargarlo automáticamente en Log Analytics, para que pueda estar directamente en LA Analizar y consultar el registro. Aunque este método es simple y conveniente, no es un método automatizado después de todo. Después de expandir nuestras ideas, podríamos intentar usar eventgrid combinado con función para convertir este método en una solución automatizada.
Primero, popularicemos primero qué son EventGrid y Function
EventGrid
Con Azure Event Grid, las aplicaciones se pueden generar fácilmente mediante una arquitectura basada en eventos. Primero, seleccione el recurso de Azure al que desea suscribirse y luego proporcione un controlador de eventos o un punto de conexión de WebHook al que enviar eventos. La cuadrícula de eventos incluye compatibilidad integrada para eventos de servicios de Azure, como blobs de almacenamiento y grupos de recursos. La cuadrícula de eventos también admite sus propios eventos utilizando temas personalizados.
En pocas palabras, es como un disparador, que puede disparar varios eventos y luego dar respuestas específicas. Suena un poco como disparadores en aplicaciones lógicas, pero eventgrid es solo una herramienta simple de transferencia de eventos, métodos de procesamiento posteriores Completamente completada por otros productos, la siguiente imagen también se puede ver donde se encuentra la cuadrícula de eventos, similar a una cola de mensajes para la transmisión de eventos.
https://docs.microsoft.com/en-us/azure/event-grid/?WT.mc_id=AZ-MVP-5001235
Función
Azure Functions es una solución sin servidor que permite a los usuarios reducir la escritura de código, reducir la infraestructura que debe mantenerse y ahorrar costos. No es necesario preocuparse por la implementación y el mantenimiento de los servidores, la infraestructura de la nube proporciona todos los recursos más recientes necesarios para mantener las aplicaciones en ejecución.
La función es realmente más fácil de entender. Ahora todas las nubes tienen básicamente productos similares. Si lo comparas horizontalmente, es AWS lambda, una plataforma de ejecución de código completamente administrada
https://docs.microsoft.com/zh-cn/azure/azure-functions/functions-overview?WT.mc_id=AZ-MVP-5001235
Combinando la figura anterior, podemos ver nuestro pensamiento. Eventgird tiene activadores de blobs incorporados, lo que significa que cuando aparece un blob nuevo, activará automáticamente eventgrid, y los procedimientos de procesamiento posteriores, podemos combinar la función para Sí, el código está realmente listo, solo use el anterior, solo necesita cambiarse ligeramente, la carga de trabajo general es muy pequeña
Por supuesto, en realidad hay un problema oculto aquí, porque el registro de la cuenta de almacenamiento se almacena en el contenedor $ logs, y este contenedor no activará la cuadrícula de eventos en el backend de Azure. Esto es un poco complicado. El método que usamos es crear una función , Y luego use azcopy para sincronizar periódicamente la sincronización de registros con otro contenedor. Solo una línea de código es fácil, por lo que no la escribiré por ahora.
Pasos de implementación
Veamos los pasos de implementación específicos a continuación. Primero, cree una aplicación de función. La relación entre la aplicación de función y la función es muy simple. La aplicación de función es equivalente a la plataforma en la que se ejecuta la función. El código se ejecuta en esta plataforma. La aplicación de función puede contener muchos Función
Crear aplicación de función
El proceso de creación de la aplicación de funciones es muy simple, elegimos el tiempo de ejecución como PowerShell Core
Crear función
Una vez creada la aplicación Función, puede crear funciones en ella. Azure en realidad tiene una función de desencadenador de cuadrícula uniforme incorporada, simplemente selecciónela al crearla
Crear suscripción a Event Grid
La función está lista, luego puede preparar eventgrid, puede crear una suscripción a la cuadrícula de eventos directamente en la función
Al crear una suscripción a la cuadrícula de eventos, hay muchos tipos que se pueden seleccionar. Aquí, elija el tipo de almacenamiento.
Configurar el tipo de evento de la cuenta de almacenamiento
Luego preste atención a la necesidad de configurar el filtro, porque tenemos que limitar la ruta a un rango específico, no todos los blobs dispararán eventos
El disparador también está listo, y luego puede preparar el código para ser procesado en la función
Escribir código
Debido a que el código anterior se procesa en un bucle, y eventgrid se empuja uno por uno, la lógica aquí debe ajustarse ligeramente
Función Build-Signature ($ customerId, $ sharedKey, $ date, $ contentLength, $ method, $ contentType, $ resource) { $ xHeaders = "x-ms-date:" + $ date $ stringToHash = $ método + "` n "+ $ contentLength +" `n" + $ contentType + "` n "+ $ xHeaders +" `n" + $ recurso $ bytesToHash = [Text.Encoding] :: UTF8.GetBytes ($ stringToHash) $ keyBytes = [Convertir ] :: FromBase64String ($ sharedKey) $ sha256 = New-Object System.Security.Cryptography.HMACSHA256 $ sha256.Key = $ keyBytes $ calculadoHash = $ sha256.ComputeHash ($ bytesToHash) $ encodedHash = [Convertir] :: ToBase64String ($ calculadoHash) $ autorización = 'SharedKey {0}: {1}' -f $ customerId,$ encodedHash return $ autorización } Función Post-LogAnalyticsData ($ customerId, $ sharedKey, $ body, $ logType) { $ method = "POST" $ contentType = "application / json" $ resource = "/ api / logs" $ rfc1123date = [DateTime] :: UtcNow .ToString ( "r") $ = $ contentLength body.Length $ = firma Build-firma ` -customerId $ customerId` -sharedKey $ sharedkey ` -date $ rfc1123date` -contentLength $ contentLength ` método $ -method` -contentType $ contentType ` -resource $ resource $ uri =" https: // "+ $ customerId +" .ods.opinsights.azure.com "+ $ resource +"? api-version = 2016-04-01 " $ headers = @ { "Autorización" = $ firma; "Tipo de registro" = $ logType; "x-ms-date" = $ rfc1123date; "campo-generado-por-tiempo" = $ TimeStampField; } $ respuesta = Invoke-WebRequest -Uri $ uri -Method $ método -ContentType $ contentType -Headers $ encabezados -Body $ body -UseBasicParsing return $ response.StatusCode } Función ConvertSemicolonToURLEncoding ([String] $ InputText) { $ ReturnText = "" $ caracteres = $ InputText.ToCharArray () $ StartConvert = $ false foreach ($ c en $ caracteres) { if ($ c -eq '"') { $ StartConvert =! $ StartConvert } if ($ StartConvert -eq $ true -and $ c -eq ';') { $ ReturnText + = "% 3B" } else { $ ReturnText + = $ c } } return $ ReturnText } Función 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 } Función ConvertLogLineToJson ([String] $ logLine) { $ logLineEncoded = ConvertSemicolonToURLEncoding ($ logLine) $ elementos = $ logLineEncoded.split (';') $ FormattedElements = New-Object System.Collections.ArrayList foreach ($ elemento en $ elementos) { $ NewText = FormalizeJsonValue ($ elemento) $ FormattedElements .Añadir ($ NewText)> null } $ Columns = ("número-versión", "hora de inicio de la solicitud", "tipo-operación", "estado-solicitud", "código-estado-http", "fin- a-latencia-final-en-ms ", " latencia-del-servidor-en-ms ", " tipo de autenticación ", "nombre-cuenta-solicitante", "nombre-cuenta-propietario", "encabezado-referente", "tipo-servicio", "url-solicitud", "clave-objeto-solicitada", "encabezado-id-solicitud", "recuento-operación", "dirección-IP-solicitante", "encabezado-solicitud-versión", "request-header-size", "request-packet-size", "response-header-size", "response-packet-size", "request-content-length", "request-md5", "server-md5 ", " identificador-etag ", " hora-de -última-modificación ", " condiciones-utilizadas ", "encabezado-agente-usuario", "id-solicitud-cliente" ) $ logJson = "[{"; Para ($ 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 "La cuenta de almacenamiento especificada no existe en esta suscripción". } $ storageContext = $ storageAccount. $ asunto = $ eventGridEvent.subject.ToString () $ BlobArray = $ sujeto.Split ('/') $ contenedor = $ BlobArray [$ BlobArray.indexof ('contenedores') + 1] $ BlobIndex = $ sujeto.indexof (' blobs / ') + 6 $ Blob = $ subject.substring ($ BlobIndex, $ subject.length - $ BlobIndex) Salida de escritura ("> Descarga de blob: {0}" -f $ blob) $ filename = ". \ log .txt " Get-AzStorageBlobContent -Context $ storageContext -Container $ container -Blob $ blob -Destination $ filename -Force> Null Write-Output ("> Publicar registros en el espacio de trabajo analítico: {0} "-f $ blob) $ líneas = Get-Content $ nombre de archivo foreach ($ línea en $ líneas) { $ json = ConvertLogLineToJson ($ línea) $ 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 "> No se pudo publicar un registro en el espacio de trabajo de Log Analytics" } } remove-item $ filename -Force Write-Output "> Líneas de registro publicadas en el espacio de trabajo de Log Analytics: éxito = $ successPost, failure = $ failedPost "
El último paso es autorizar a la aplicación de función a acceder al almacenamiento. Este paso no se discutirá en detalle. También puedes usar la clave de la cuenta de almacenamiento para hacerlo. Por supuesto, este método no es muy recomendable.
Finalmente, puede ver el efecto completo en el monitoreo en la función
para resumir
En términos generales, no ha cambiado mucho en comparación con la forma de usar simplemente scripts de PowerShell, pero debido a la adición de eventgrid y funciones, toda la solución se ha vuelto más flexible. Ideas similares también se pueden extender a muchas otras tareas para estar más basadas en la nube. para mirar y tratar los problemas de forma nativa