如何在Azure Blob中实现多文件夹文件迁移及审计记录?
Azure Blob存储自动迁移+审计实现方案
整体架构思路
采用Azure Blob触发器的Azure Function监听目标文件上传事件,自动执行Blob迁移(复制+删除源文件)操作,并将操作日志写入审计表(推荐Azure SQL或Cosmos DB)。
步骤1:创建Blob触发的Azure Function
- 触发器路径配置:设置为
app_archive/{appName}/{fileName},仅监听app_archive下直接子目录(app1~app150)中的csv文件,避免触发已迁移到日期子目录的文件。 - 存储连接配置:在Function应用的配置项中添加
AzureWebJobsStorage,填入你的Blob存储账户连接字符串。
步骤2:编写Blob迁移逻辑
使用Azure.Storage.Blobs SDK实现文件复制与删除,核心代码示例(C#):
[FunctionName("BlobMigrationFunction")] public async Task Run( [BlobTrigger("app_archive/{appName}/{fileName}", Connection = "AzureWebJobsStorage")] Stream blobStream, string appName, string fileName, ILogger log) { var blobServiceClient = new BlobServiceClient(Environment.GetEnvironmentVariable("AzureWebJobsStorage")); var containerClient = blobServiceClient.GetBlobContainerClient("Container"); // 替换为你的容器名称 var sourceBlob = containerClient.GetBlobClient($"app_archive/{appName}/{fileName}"); // 生成目标路径(采用UTC时间的年月日层级) var currentDate = DateTime.UtcNow; var targetPath = $"app_archive/{appName}/{currentDate.Year}/{currentDate.Month:D2}/{currentDate.Day:D2}/{fileName}"; var targetBlob = containerClient.GetBlobClient(targetPath); try { // 复制源Blob到目标路径 await targetBlob.StartCopyFromUriAsync(sourceBlob.Uri); // 等待复制操作完成 await WaitForCopyCompletion(targetBlob, log); // 删除源Blob,完成迁移 await sourceBlob.DeleteAsync(); // 记录成功审计日志 await LogAudit(fileName, sourceBlob.Uri.ToString(), targetBlob.Uri.ToString(), "Success"); log.LogInformation($"迁移完成:{fileName} -> {targetPath}"); } catch (Exception ex) { log.LogError(ex, $"迁移失败:{fileName}"); // 记录失败审计日志 await LogAudit(fileName, sourceBlob.Uri.ToString(), targetBlob.Uri.ToString(), $"失败:{ex.Message}"); throw; } } // 辅助方法:等待复制操作完成 private async Task WaitForCopyCompletion(BlobClient targetBlob, ILogger log) { BlobProperties props; do { props = await targetBlob.GetPropertiesAsync(); if (props.CopyStatus == CopyStatus.Pending) { await Task.Delay(1000); } } while (props.CopyStatus == CopyStatus.Pending); if (props.CopyStatus != CopyStatus.Success) { throw new InvalidOperationException($"复制状态异常:{props.CopyStatus}"); } }
步骤3:实现审计记录功能
3.1 创建审计表(以Azure SQL为例)
执行以下SQL语句创建审计日志表:
CREATE TABLE AuditLogs ( AuditId INT IDENTITY(1,1) PRIMARY KEY, SourceFileName NVARCHAR(255) NOT NULL, SourceFilePath NVARCHAR(1000) NOT NULL, TargetFilePath NVARCHAR(1000) NOT NULL, OperationTime DATETIME NOT NULL DEFAULT GETUTCDATE(), Status NVARCHAR(100) NOT NULL );
3.2 编写审计日志插入逻辑
在Function中添加日志插入方法:
private async Task LogAudit(string fileName, string sourcePath, string targetPath, string status) { var connString = Environment.GetEnvironmentVariable("AuditDBConnection"); using var conn = new SqlConnection(connString); await conn.OpenAsync(); var insertCmd = @"INSERT INTO AuditLogs (SourceFileName, SourceFilePath, TargetFilePath, Status) VALUES (@FileName, @SourcePath, @TargetPath, @Status)"; using var cmd = new SqlCommand(insertCmd, conn); cmd.Parameters.AddWithValue("@FileName", fileName); cmd.Parameters.AddWithValue("@SourcePath", sourcePath); cmd.Parameters.AddWithValue("@TargetPath", targetPath); cmd.Parameters.AddWithValue("@Status", status); await cmd.ExecuteNonQueryAsync(); }
- 在Function应用配置中添加
AuditDBConnection,填入你的SQL数据库连接字符串。
关键配置与注意事项
- 权限配置:给Azure Function的身份(系统分配/用户分配)添加Storage Blob Data Contributor(Blob存储)和db_datawriter(SQL数据库)权限,避免硬编码密钥。
- 日期逻辑:若需使用文件创建日期而非触发时间,可从
sourceBlob.Properties.CreatedOn获取日期值替换当前时间。 - 重复文件处理:若目标路径已存在同名文件,可添加覆盖逻辑(
targetBlob.UploadAsync)或抛出异常,根据业务需求调整。 - 低代码替代:若无需编写代码,可使用Azure Logic Apps配置Blob触发器+复制Blob动作+SQL插入动作,实现相同逻辑。
内容的提问来源于stack exchange,提问作者Bhaskar
相关产品推荐
相关产品推荐

