在GO中使用日志库slog

本文根据三篇文章机翻拼凑而来。其中两篇文章发布时,slog还未进入标准库。golang 1.21.0 于2023-08-09发布,slog也包含在正式库中,本文根据原文内容进行了部分的修订和补充。 什么是slog? slog 是 Go 团队的一个实验性日志记录包,提供结构化日志记录的功能。 本文向您概述了此包中的日志记录功能。 安装 # 创建一个新的 go 项目并引入 log/slog 使用记录器# 立即导入并开始使用记录器。 package main import ( "log/slog" ) func main() { slog.Info("Go is best language!") } 输出: $ go run main.go 2022/12/15 01:31:23 INFO Go is best language! 默认情况下,输出包括时间、日志级别和消息。 以下日志级别可用。 Debug Info Warn Error 结构化日志# slog 是一个结构化记录器,支持两种格式的日志记录:文本和 json。 让我们看一下文本记录器。 文本处理程序# 您首先创建一个文本处理程序和一个新的记录器。 package main import ( "os" "log/slog" ) func main() { textHandler := slog.NewTextHandler(os.Stdout,nil) logger := slog....

HashiCorp go-plugin包使用指南

1. 介绍 HashiCorp的go-plugin包是一个强大的Go语言插件系统,它通过RPC实现主程序和插件之间的通信。这个系统被广泛应用于HashiCorp的多个项目中,如Terraform、Nomad、Vault、Boundary和Waypoint等。本文将循序渐进地介绍go-plugin的使用方法,并提供简单易复现的例子。 2. 基本概念 go-plugin的工作原理是启动子进程并通过RPC进行通信。它支持标准的net/rpc和gRPC两种通信方式。主要特点包括: 插件是Go接口的实现 支持跨语言插件 支持复杂参数和返回值 支持双向通信 内置日志功能 协议版本控制 支持stdout/stderr同步 TTY保留 插件运行时主机升级 加密安全的插件 3. 单向通信示例 让我们从一个简单的单向通信示例开始,实现一个基本的问候插件。 3.1 定义接口 首先,我们需要定义插件将要实现的接口: // shared/interface.go package shared import "context" type Greeter interface { Greet(ctx context.Context, name string) (string, error) } 3.2 实现插件 接下来,我们实现这个接口作为一个插件: // plugin/main.go package main import ( "context" "fmt" "github.com/hashicorp/go-plugin" "path/to/your/shared" ) type GreeterPlugin struct{} func (g *GreeterPlugin) Greet(ctx context.Context, name string) (string, error) { return fmt.Sprintf("Hello, %s!", name), nil } var handshakeConfig = plugin....

如何为七牛已绑定域名的bucket获取Let's Encrypt证书

关于Let’s Encrypt证书 官网的说明是 一个为 2.25 亿个网站提供 TLS 证书的非盈利性证书颁发机构。 官网 : https://letsencrypt.org/zh-cn/ 获取证书的验证方式 目前有很多自动工具可以获取,需要有相关的域名或者服务器权限。认证的方式有三种,这里引用下官网的说明。验证方式 当您从 Let’s Encrypt 获得证书时,我们的服务器会验证您是否使用 ACME 标准定义的验证方式来验证您对证书中域名的控制权。 大多数情况下,验证由 ACME 客户端自动处理,但如果您需要做出一些更复杂的配置决策,那么了解更多有关它们的信息会很有用。 如果您不确定怎么做,请使用您的客户端的默认设置或使用 HTTP-01。 HTTP-01 验证 这是当今最常见的验证方式。 Let’s Encrypt 向您的 ACME 客户端提供一个令牌,然后您的 ACME 客户端将在您对 Web 服务器的 http://<你的域名>/.well-known/acme-challenge/(用提供的令牌替换 )路径上放置指定文件。 该文件包含令牌以及帐户密钥的指纹。 一旦您的 ACME 客户端告诉 Let’s Encrypt 文件已准备就绪,Let’s Encrypt 会尝试获取它(可能从多个地点进行多次尝试)。 如果我们的验证机制在您的 Web 服务器上找到了放置于正确地点的正确文件,则该验证被视为成功,您可以继续申请颁发证书。 如果验证检查失败,您将不得不再次使用新证书重新申请。 我们的 HTTP-01 验证最多接受 10 次重定向。 我们只接受目标为“http:”或“https:”且端口为 80 或 443 的重定向。 我们不目标为 IP 地址的重定向。 当被重定向到 HTTPS 链接时,我们不会验证证书是否有效(因为验证的目的是申请有效证书,所以它可能会遇到自签名或过期的证书)。 HTTP-01 验证只能使用 80 端口。 因为允许客户端指定任意端口会降低安全性,所以 ACME 标准已禁止此行为。...

Buf使用备忘

Buf 工具针对于Schema驱动、基于 Protobuf 的 API 开发,为服务发布者和服务客户端提供可靠和更好的用户体验。简化了您的 Protobuf 管理策略,以便您可以专注于重要的事情。 下载安装 可以直接去buf的GitHub的release页面下载,其他的安装方式参考官方文档 使用 三个yaml文件 初次接触buf项目的时候,有个疑问就是buf项目中buf.yaml buf.gen.yaml buf.work.yaml这个三个文件的区别和用途。下面是简单的一个表,列出了三个文件的区别: 文件名 文件位置 说明 buf.yaml 每个proto模块定义的根目录 buf.yaml 配置的位置告诉 buf 在哪里搜索 .proto 文件,模块的依赖项以及如何处理导入 buf.gen.yaml 一般放在仓库的根目录 文件控制 buf generate 命令如何针对任何输入执行 protoc 插件 buf.work.yaml 一般放在仓库的根目录 定义项目需要哪些proto模块 示例目录结构: . ├── buf.gen.yaml ├── buf.work.yaml ├── proto │ ├── acme │ │ └── weather │ │ └── v1 │ │ └── weather.proto │ └── buf.yaml └── vendor └── protoc-gen-validate ├── buf.yaml └── validate └── validate....

Golang高效解码xml文件

xml处理需要引用encoding/xml包.一般推荐使用 xml.Decoder 替代 xml.Unmarshal。 xml.Decoder 是一个流式 XML 解码器,它可以边读取边解码,而不需要将整个 XML 文档加载到内存中。相比之下,xm1.Unmarshal 会将整个 XML 文档加载到内存中然后再进行解码。因此,对于大型 XML 文件,使用xml.Decoder 可以节省内存并提高性能。 小的Xml文件 下面是一个例子 package main import ( "encoding/xml" "os" "testing" ) type UserData struct { Name string `xml:"name"` Age int32 `xml:"age"` } type Pocket struct { Data []UserData `xml:"users"` } func TestXmlDecode(t *testing.T) { file, err := os.Open("testdata/userdata.xml") if err != nil { t.Fatal(err) } var pocket Pocket if err := xml.NewDecoder(file).Decode(&pocket); err != nil { t....

Golang 防火墙编程

非编程方式 Windows 使用netsh方式进行防火墙规则的维护 Linux 编程方式 Windows Tailscale开发了一个应用WFP的库inet.af/wf 。参考参考链接。在tailscale中的封装代码如下(源链接): // Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause //go:build windows package wf import ( "fmt" "net/netip" "os" "golang.org/x/sys/windows" "inet.af/wf" "tailscale.com/net/netaddr" ) // Known addresses. var ( linkLocalRange = netip.MustParsePrefix("ff80::/10") linkLocalDHCPMulticast = netip.MustParseAddr("ff02::1:2") siteLocalDHCPMulticast = netip.MustParseAddr("ff05::1:3") linkLocalRouterMulticast = netip.MustParseAddr("ff02::2") ) type direction int const ( directionInbound direction = iota directionOutbound directionBoth ) type protocol int const ( protocolV4 protocol = iota protocolV6 protocolAll ) // getLayers returns the wf....

使用aws go-sdk访问cloudflare R2文件

准备 需要准备Cloudflare的accountId,相应的R2 ak sk 和bucketName等信息. var ( accountId = "xxxxx" accessKeyId = "cbdade718b2ca877882csssssfcf" accessKeySecret = "04917c7d745422022e266f6b06" bucketName = "gopher" ) 完整代码 package main import ( "context" "fmt" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" "log" ) func main() { var ( accountId = "xxxxx" accessKeyId = "cbdade718b2ca877882csssssfcf" accessKeySecret = "04917c7d745422022e266f6b06" bucketName = "gopher" ) var r2Resolver = aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) { return aws.Endpoint{ URL: fmt.Sprintf("https://%s.r2.cloudflarestorage.com", accountId), }, nil }) cfg, err := config....

在树莓派3b上部署minio服务

安装 我的树莓派安装的是manjaro,直接执行如下命令即可 yay -S minio 官方的安装文档开源参考 https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-single-node-single-drive.html 启用服务 systemctl enable minio 修改配置 主要修改mino的设置文件,文件位置为/etc/minio/minio.conf # Local export path. MINIO_VOLUMES="/srv/minio/data/" # Server user. MINIO_ROOT_USER=gopher # Server password. MINIO_ROOT_PASSWORD=gopher # Use if you want to run Minio on a custom port. MINIO_OPTS="--console-address :8888" MINIO_SERVER_URL="https://minio.xxx.org" MINIO_BROWSER_REDIRECT_URL="https://minio-console.xxx.org" 修改 MINIO_OPTS 主要是为了自定义Console的端口,而这个参数主要是在service定义中使用,安装软件后自动使用的service(路径为/usr/lib/systemd/system/minio.service)定义如下 [Unit] Description=Minio Documentation=https://docs.minio.io Wants=network-online.target After=network-online.target AssertFileIsExecutable=/usr/bin/minio [Service] # Specifies the maximum file descriptor number that can be opened by this process LimitNOFILE=65536 Type=simple User=minio Group=minio EnvironmentFile=/etc/minio/minio....

【译】如何使用 http.ResponseController 类型

本文原文地址 https://www.alexedwards.net/blog/how-to-use-the-http-responsecontroller-type,使用chatGPT翻译 One of my favorite things about the recent Go 1.20 release is the new http.ResponseController type, which brings with it three nice benefits: 关于最近的 Go 1.20 版本,我最喜欢的事情之一是新的 http.ResponseController 类型,它带来了三个好处: You can now override your server-wide read and write deadlines on a per request basis. 您现在可以根据每个请求覆盖服务器范围内的读取和写入截止日期。 The pattern for using the http.Flusher and http.Hijacker interfaces is clearer and feels less hacky. No more type assertions necessary! 使用 http.Flusher 和 http....

golang CGO参考

开源项目 https://github.com/dolthub/go-library-sample https://github.com/draffensperger/go-interlang https://github.com/kbehouse/go_call_cxx_so https://github.com/tailscale/libtailscale https://github.com/iikira/golang-msvc https://github.com/vladimirvivien/go-cshared-examples https://github.com/tailscale/libtailscale/tree/main 文档 Embedding Go in C Calling C code from go C? Go? Cgo! CGO编程(Go语言高级编程) https://stackoverflow.com/questions/14581063/golang-cgo-converting-union-field-to-go-type https://sunzenshen.github.io/tutorials/2015/05/09/cgotchas-intro.html https://totallygamerjet.hashnode.dev/the-smallest-go-binary-5kb 代码片段 Convert ‘C’ array to golang slice func carray2slice(array *C.int, len int) []C.int { var list []C.int sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&list))) sliceHeader.Cap = len sliceHeader.Len = len sliceHeader.Data = uintptr(unsafe.Pointer(array)) return list }