美文网首页
【Go - 10分钟,快速搭建一个简易日志回传系统】

【Go - 10分钟,快速搭建一个简易日志回传系统】

作者: wn777 | 来源:发表于2024-08-31 14:40 被阅读0次

    上周一个平凡的工作日傍晚,快要下班的时候,客户端新产品线负责人突然火急火燎的找到我 ,说新的APP马上要release了,发现还少个APP异常崩溃时,用户上报日志的功能 ,需要后端支持,提供个日志回传接口。

    时间紧,立刻开始行动。提供个接口 ,自然不是难题,但是只需要提供一个接口吗?我知道这很急,但先别急,

    流程

    先来拆解下这个需求,用户从APP上报问题日志后 ,要有个服务接收然后存储,存储完 后续对应研发 还要能进行检索查看,所以整体流程。

    这其中就涉及到,

    日志回传服务

    • http 上传接口
    • 接口身份验证 (多选一)
      • ak、sk
      • 静态token

    日志检索

    • 日志检索
    • 日志查看
    • 用户权限

    部署

    • 固定域名
      • 日志回传服务 需要一个固定域名
    • 服务运行环境 (多选一)
      • 物理机
      • serverless

    任务不重,但时间紧。废话不多说,需求清晰了,啪啪啪几下,先出个实现方案,这里我们以填空的方式 把实现填到上面的流程上。

    实现

    日志回传服务可以搭建一个http服务,日志文件上传Post 提交表单的形式。
    日志存储可以选用 阿里云oss存储, ES等,甚至可以直接放到本地。
    日志检索可以依赖 阿里云oss控制台,权限管理,查看都有对应配套。

    那么接下来,上代码

    代码

    http 服务器,搭建一个简易日志回传服务

    package main
    
    import (
        "fmt"
        "mime/multipart"
        "net/http"
        "os"
    
        "github.com/gin-gonic/gin"
    )
    
    func handleError(err error) {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    
    func Auth() gin.HandlerFunc {
        return func(c *gin.Context) {
            // 获取请求头中的Token
            token := c.GetHeader("Token")
            if token == "" {
                c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is required"})
                c.Abort()
                return
            }
    
            // 验证Token是否有效
            if token != "my_token" {
                c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid Token"})
                c.Abort()
                return
            }
    
            // 继续往下处理
            c.Next()
        }
    }
    
    func saveToOSS(c *gin.Context, file *multipart.FileHeader) error {
        // Init oss client
        client := getSingletonOssClient()
        // yourBucketName填写存储空间名称。
        bucketName := "${your_bucket_name}"
        // yourObjectName填写Object完整路径,完整路径不包含Bucket名称。
        objectPath := "${path}"
        // 获取存储空间。
        bucket, err := client.Bucket(bucketName)
        if err != nil {
            handleError(err)
        }
    
        // 临时保存文件到本地
        filePath := "./uploads/" + file.Filename
        err = c.SaveUploadedFile(file, filePath)
        // 上传完成后删除文件
        defer os.Remove(filePath)
        if err != nil {
            return err
        }
        // 上传文件到OSS
        objectName := objectPath + "/" + file.Filename
        err = bucket.PutObjectFromFile(objectName, filePath)
        if err != nil {
            return err
        }
        return nil
    }
    
    func main() {
        router := gin.Default()
    
        router.Use(Auth())
    
        // 定义文件上传的POST接口
        router.POST("/upload", func(c *gin.Context) {
            // 从请求中获取文件
            file, err := c.FormFile("file")
            if err != nil {
                c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
                return
            }
            // 这里存储方式,选择存储到阿里云OSS
            err = saveToOSS(c, file)
            if err != nil {
                c.String(http.StatusInternalServerError, fmt.Sprintf("upload file err: %s", err.Error()))
                return
            }
            c.String(http.StatusOK, fmt.Sprintf("File %s uploaded successfully.", file.Filename))
        })
    
        router.Run(":8080")
    }
    
    

    存储层,这里选用阿里云OSS

    package main
    
    import (
        "fmt"
        "os"
    
        "github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    func getSingletonOssClient() *oss.Client {
        // 填写你自己的AK
        os.Setenv("OSS_ACCESS_KEY_ID", "${your_ak}")
        // 填写你自己的SK
        os.Setenv("OSS_ACCESS_KEY_SECRET", "${your_sk}")
    
        provider, err := oss.NewEnvironmentVariableCredentialsProvider()
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
        // 创建OSSClient实例。
        // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,
        // 填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
        endpoint := "<https://oss-cn-hangzhou.aliyuncs.com>"
        client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
        if err != nil {
            handleError(err)
        }
        fmt.Printf("client:%#v\\n", client)
        return client
    
    }
    
    

    至此便快速搭建了一个简易的日志回传系统, 调用试一下

    curl -X POST <http://localhost:8080/upload> -F "file=@/${your_log_path}/a.log" -H "Token: my_token"
    
    

    OK,完成回传。



    相关文章

      网友评论

          本文标题:【Go - 10分钟,快速搭建一个简易日志回传系统】

          本文链接:https://www.haomeiwen.com/subject/hvyqljtx.html