Code Monkey home page Code Monkey logo

iam's Introduction

IAM - 身份识别与访问管理系统

欢迎加入我的新课程 孔令飞的云原生实战营,带你进阶为 Go + 云原生高级开发工程师。

IAM = Identity and Access Management

IAM 是一个基于 Go 语言开发的身份识别与访问管理系统,用于对资源访问进行授权。最新稳定版本为:v1.6.2,建议基于稳定版安装测试

这里需要注意:

  • 如果你是极客时间《Go 语言项目开发实战》专栏的读者,请使用 v1.1.0 版本(tag)
  • 如果你是图书《从零构建企业级 Go 项目》的读者,请使用 v1.6.t2 版本(tag)

更详细的版本映射请参考:版本映射

IAM 同时也具有以下能力:

  1. 配合极客时间专栏 Go 语言项目开发实战,讲解如何用 Go 做企业级应用的开发,是该项目的理论课程,包含了项目各个知识点和构建思路的讲解,也会包含我的一线研发经验和建议。

  2. 作为一个开发脚手架,供开发者克隆后二次开发,快速构建自己的应用。

IAM 项目会长期维护、定期更新,欢迎兄弟们 Star & Contribute

功能特性

本项目用到了Go企业开发的大部分核心技能点,见下图:

技术思维导图

更多请参考:marmotedu/gocollect

软件架构

IAM架构

架构解析见:IAM 架构 & 能力说明

快速开始

依赖检查

  1. 服务器能访问外网

  2. 操作系统:CentOS Linux 8.x (64-bit)

本安装脚本基于 CentOS 8.2 安装,建议你选择 CentOS 8.x 系统。其它Linux发行版、macOS也能安装,不过需要手动安装。

快速部署

快速部署请参考:IAM 部署指南

IAM 项目还提供了更详细的部署文档,请参考:手把手教你部署IAM系统

构建

如果你需要重新编译IAM项目,可以执行以下 2 步:

  1. 克隆源码
$ git clone https://github.com/marmotedu/iam $GOPATH/src/github.com/marmotedu/iam
  1. 编译
$ cd $GOPATH/src/github.com/marmotedu/iam
$ make

构建后的二进制文件保存在 _output/platforms/linux/amd64/ 目录下。

使用指南

IAM Documentation

如何贡献

欢迎贡献代码,贡献流程可以参考 developer's documentation

社区

You are encouraged to communicate most things via GitHub issues or pull requests.

关于作者

为了方便交流,我建了微信群,可以加我 微信:nightskong,拉你入群,方便交流。

谁在用

如果你有项目在使用iam系统模板,也欢迎联系作者,加入使用案例。

许可证

IAM is licensed under the MIT. See LICENSE for the full license text.

iam's People

Contributors

colin404 avatar dairongpeng avatar heisaman avatar housemecn avatar joeyscat avatar jyokotori avatar kyle-ip avatar leilei3167 avatar liuhaonan00 avatar loyalsoldier avatar lucareful avatar maogou avatar maplepie avatar ppd0705 avatar shepf avatar suexcxine avatar yandongxiao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iam's Issues

why always new Validator?

github.com/marmotedu/api/apiserver/v1/validate.go

func (u *User) Validate() field.ErrorList {
val := validation.NewValidator(u)
......
}

func (u *User) ValidateUpdate() field.ErrorList {
val := validation.NewValidator(u)
.......
}

// Validate validates that a secret object is valid.
func (s *Secret) Validate() field.ErrorList {
val := validation.NewValidator(s)

return val.Validate()

}

// Validate validates that a policy object is valid.
func (p *Policy) Validate() field.ErrorList {
val := validation.NewValidator(p)

return val.Validate()

}

in the end
func NewValidator(data interface{}) *Validator {
result := validator.New()
......
}
//New returns a new instance of 'validate' with sane defaults. Validate is designed to be thread-safe and used as a singleton instance. //It caches information about your struct and validations, in essence only parsing your validation tags once per struct type. Using //multiple instances neglects the benefit of caching.
validator.New()

l think result can be single instance,there is no need to create an validator instance everytime NewValidator function is called
Am l right?

some docs need to update

When I was fixing a bug, I encountered the problem that the code could not be pushed to the remote repository.

error: src refspec main does not match any
error: failed to push some refs to 'https://github.com/cyb0225/iam-1.git'

I trid to find the solution and successfully I found the .git/hooks/commit-msg file.

# Copyright 2020 Lingfei Kong <[email protected]>. All rights reserved.
# Use of this source code is governed by a MIT style
# license that can be found in the LICENSE file.

# Store this file as .git/hooks/commit-msg in your repository in order to
# enforce checking for proper commit message format before actual commits. You
# may need to make the script executable by 'chmod +x .git/hooks/commit-msg'.

# commit-msg use go-gitlint tool, install go-gitlint via `go get github.com/llorllale/go-gitlint/cmd/go-gitlint`
go-gitlint --msg-file="$1"

I installed go-gitlint according to the comments, but it didn't work. And I found that in the higher version of the go language installation tool should use "go install" instead of "go get".

So I think some docs may be too old to solve problems.

此架构与微服务架构的区别

看项目中有 auth-server和api-server,此架构适用于微服务吗?如果是微服务,是不是要将每个服务独立到单独的go mod中会比较好,而不是先通过功能分层(如cmd,internal),然后再进行领域分层(如auth-server, api-server)?还请老师指点

直接make报codegen

===========> Installing codegen
===========> Generating iam error code go source files
/bin/bash: line 1: codegen: command not found

iam/configs/iam-apiserver.yaml 中缺少error-output-paths 配置项缺少$符号

log:
    name: apiserver # Logger的名字
    development: true # 是否是开发模式。如果是开发模式,会对DPanicLevel进行堆栈跟踪。
    level: debug # 日志级别,优先级从低到高依次为:debug, info, warn, error, dpanic, panic, fatal。
    format: console # 支持的日志输出格式,目前支持console和json两种。console其实就是text格式。
    enable-color: true # 是否开启颜色输出,true:是,false:否
    disable-caller: false # 是否开启 caller,如果开启会在日志中显示调用日志所在的文件、函数和行号
    disable-stacktrace: false # 是否再panic及以上级别禁止打印堆栈信息
    output-paths: ${IAM_LOG_DIR}/iam-apiserver.log,stdout # 支持输出到多个输出,逗号分开。支持输��到标准输出(stdout)和文件。
    error-output-paths: {IAM_LOG_DIR}/iam-apiserver.error.log # zap内部(非业务)错误日志输出路径,多个输出,逗号分开

最后一行应该为: error-output-paths: ${IAM_LOG_DIR}/iam-apiserver.error.log

关于GenericAPIServer启动的设计问题

老师关于这段代码有两个疑问

var eg errgroup.Group
// Initializing the server in a goroutine so that
// it won't block the graceful shutdown handling below
eg.Go(func() error {
log.Infof("Start to listening the incoming requests on http address: %s", s.InsecureServingInfo.Address)
if err := s.insecureServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal(err.Error())
return err
}
log.Infof("Server on %s stopped", s.InsecureServingInfo.Address)
return nil
})
eg.Go(func() error {
key, cert := s.SecureServingInfo.CertKey.KeyFile, s.SecureServingInfo.CertKey.CertFile
if cert == "" || key == "" || s.SecureServingInfo.BindPort == 0 {
return nil
}
log.Infof("Start to listening the incoming requests on https address: %s", s.SecureServingInfo.Address())
if err := s.secureServer.ListenAndServeTLS(cert, key); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal(err.Error())
return err
}
log.Infof("Server on %s stopped", s.SecureServingInfo.Address())
return nil
})
// Ping the server to make sure the router is working.
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if s.healthz {
if err := s.ping(ctx); err != nil {
return err
}
}
if err := eg.Wait(); err != nil {
log.Fatal(err.Error())
}

  1. 这一段代码为啥ping不让它一直自己进行检测,然后用eg.Go去进行处理s.ping方法,如果用这个岂不是可以直接使ping和http、https一起管理如果ping不通则说明服务不可用要关闭么?
  2. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)的context为啥不使用errgroup.WithContext使其保持一致?

Makefile中的install.install是否应该移除?

## install: Install iam system with all its components.
.PHONY: install
install:
	@$(MAKE) install.install

install.install并未在其他的文件中被定义,是否需要将其删除?或者新增一个install.mk文件,在其中定义执行自动安装项目的target逻辑?

微信加不了?

为了方便交流,我建了微信群,可以加我 微信:marmotedu,拉你入群,方便交流。


貌似微信搜索,该用户不存在

OS

孔老师你好:
1.非常抱歉,购买了书籍之后,信誓旦旦打开学习,死在了第一步,M2架构的电脑着实没有寻找到CentOS8.4的iso镜像。(上云成本太高)。(emmm,即使寻找到了iso,arm架构的yum源,emm...hhhh)
2. 采用CentOS7.9 影响很大吗。

internal/authzserver/server.go 中 stopCh 感觉没有什么用

stopCh 的作用应该是为了当前 goroutine 不退出,但是 这个 chan 只有读取,没有写入,没有地方控制chan 会导致无法退出

感觉不用 stopCh 也可以 s.genericAPIServer.Run() 本身 就会阻塞 goroutine ,s.genericAPIServer.Close() 也会导致 当前方法退出

func (s preparedAuthzServer) Run() error {
	// start shutdown managers
	if err := s.gs.Start(); err != nil {
		log.Fatalf("start shutdown manager failed: %s", err.Error())
	}

	// in order to ensure that the reported data is not lost,
	// please ensure the following graceful shutdown sequence
	s.gs.AddShutdownCallback(shutdown.ShutdownFunc(func(string) error {
		s.genericAPIServer.Close()
		if s.analyticsOptions.Enable {
			analytics.GetAnalytics().Stop()
		}
		s.redisCancelFunc()

		return nil
	}))

	return s.genericAPIServer.Run()
}

Uninstall should be install

The following two lines should be corrected with install not uninstall in iam/docs/guide/zh-CN/installation/04_install_iam.md

cd /tmp/iam && ./scripts/install/iamctl.sh iam::iamctl::uninstall -->cd /tmp/iam && ./scripts/install/iamctl.sh iam::iamctl::install
cd /tmp/iam && ./scripts/install/man.sh iam::man::uninstall -->cd /tmp/iam && ./scripts/install/man.sh iam::man::install

Uninstall issues

go.mod replace 路径错误

replace (
	github.com/marmotedu/api => /home/colin/workspace/golang/src/github.com/marmotedu/api
	github.com/marmotedu/component-base => /home/colin/workspace/golang/src/github.com/marmotedu/component-base
)

安装会提示路径错误,go.mod中replace删除才能安装

hello I want to ask some question

I was prompted step by step to install, but finally reported an error

Exiting with status 1
[root@localhost iam]# cd /tmp/iam/ && ./scripts/install/test.sh iam::test::test
!!! [0409 06:57:41] Call tree:
!!! [0409 06:57:41]  1: ./scripts/install/test.sh:112 iam::test::user(...)
!!! [0409 06:57:41]  2: ./scripts/install/test.sh:232 iam::test::apiserver(...)
!!! [0409 06:57:41]  3: ./scripts/install/test.sh:242 iam::test::smoke(...)
!!! [0409 06:57:41]  4: ./scripts/install/test.sh:249 iam::test::test(...)
!!! Error in ./scripts/install/test.sh:29
  Error in ./scripts/install/test.sh:29. '((i<6-1))' exited with status 1
Call stack:
  1: ./scripts/install/test.sh:29 iam::test::user(...)
  2: ./scripts/install/test.sh:112 iam::test::apiserver(...)
  3: ./scripts/install/test.sh:232 iam::test::smoke(...)
  4: ./scripts/install/test.sh:242 iam::test::test(...)
  5: ./scripts/install/test.sh:249 main(...)

提供的包下载地址似乎失效了

[going@dev iam]$ version=1.1.0 && curl https://marmotedu-1254073058.cos.ap-beijing.myqcloud.com/iam-release/${version}/iam.tar.gz

UnavailableForLegalReasons Your account has been banned for the reason of violations, please delete the illegal objects. marmotedu-1254073058.cos.ap-beijing.myqcloud.com/iam-release/1.1.0/iam.tar.gz NjJiZmE1YjZfNGRjZjM4MGJfN2FlZF81NjZkMzRk OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTVmYzc0YmEzZDg5YTVjMDA4YzA3ZWY5ZjQwZTE2ZGU1NDIzMTk4YTA3NzNhMmIzMWZhMTNhNWM2NmVmMDc5MmM=

Compiling the iam-authz-server component failed

Issue Description:

$ make build BINS=iam-authz-server
github.com/marmotedu/iam/cmd/iam-authz-server
cmd/iam-authz-server/authzserver.go:18:2: undefined: authzserver
make[1]: *** [scripts/make-rules/golang.mk:56: go.build.linux_amd64.iam-authz-server] Error 1
make: *** [Makefile:62: build] Error 2

$go build -v cmd/iam-authz-server/authzserver.go
command-line-arguments
cmd/iam-authz-server/authzserver.go:18:2: undefined: authzserver

To resolve this issue, add the following package dependency in the authzserver.go file:

import (
	"math/rand"
	"time"
	"github.com/marmotedu/iam/internal/authzserver"
)

同学,您这个项目引入了632个开源组件,存在28个漏洞,辛苦升级一下

检测到 marmotedu/iam 一共引入了632个开源组件,存在28个漏洞

漏洞标题:jwt-go 安全漏洞
缺陷组件:github.com/dgrijalva/[email protected]+incompatible
漏洞编号:CVE-2020-26160
漏洞描述:jwt-go是个人开发者的一个Go语言的JWT实现。
jwt-go 4.0.0-preview1之前版本存在安全漏洞。攻击者可利用该漏洞在使用[]string{} for m[\"aud\"](规范允许)的情况下绕过预期的访问限制。
影响范围:(∞, 4.0.0-preview1)
最小修复版本:4.0.0-preview1
缺陷组件引入路径:github.com/marmotedu/iam@->github.com/marmotedu/[email protected]>github.com/dgrijalva/[email protected]+incompatible
github.com/marmotedu/iam@->github.com/marmotedu/[email protected]>github.com/marmotedu/[email protected]>github.com/dgrijalva/[email protected]+incompatible
github.com/marmotedu/iam@->github.com/marmotedu/[email protected]>github.com/marmotedu/[email protected]>github.com/dgrijalva/[email protected]+incompatible
github.com/marmotedu/iam@->github.com/marmotedu/[email protected]>github.com/dgrijalva/[email protected]+incompatible
github.com/marmotedu/iam@->github.com/appleboy/gin-jwt/[email protected]>github.com/dgrijalva/[email protected]+incompatible
github.com/marmotedu/iam@->github.com/dgrijalva/[email protected]+incompatible
github.com/marmotedu/iam@->github.com/marmotedu/[email protected]>github.com/marmotedu/[email protected]>github.com/dgrijalva/[email protected]+incompatible
github.com/marmotedu/iam@->github.com/marmotedu/[email protected]>github.com/dgrijalva/[email protected]+incompatible

另外还有28个漏洞,详细报告:https://mofeisec.com/jr?p=aa1acc

genconfig.sh第26行set命令似乎有点问题

在man set下好像没有看到set +u的用法,请问这是特殊的用法吗

man set
Options:
-a Mark variables which are modified or created for export.
-b Notify of job termination immediately.
-e Exit immediately if a command exits with a non-zero status.
-f Disable file name generation (globbing).
-h Remember the location of commands as they are looked up.
-k All assignment arguments are placed in the environment for a
command, not just those that precede the command name.
-m Job control is enabled.
-n Read commands but do not execute them.
-o option-name
Set the variable corresponding to option-name:
allexport same as -a
braceexpand same as -B
emacs use an emacs-style line editing interface
errexit same as -e
errtrace same as -E
functrace same as -T
hashall same as -h
histexpand same as -H
history enable command history
ignoreeof the shell will not exit upon reading EOF
interactive-comments
allow comments to appear in interactive commands
keyword same as -k
monitor same as -m
noclobber same as -C
noexec same as -n
noglob same as -f
nolog currently accepted but ignored
notify same as -b
nounset same as -u
onecmd same as -t
physical same as -P
pipefail the return value of a pipeline is the status of
the last command to exit with a non-zero status,
or zero if no command exited with a non-zero status
posix change the behavior of bash where the default
operation differs from the Posix standard to
match the standard
privileged same as -p
verbose same as -v
vi use a vi-style line editing interface
xtrace same as -x
-p Turned on whenever the real and effective user ids do not match.
Disables processing of the $ENV file and importing of shell
functions. Turning this option off causes the effective uid and
gid to be set to the real uid and gid.
-t Exit after reading and executing one command.
-u Treat unset variables as an error when substituting.
-v Print shell input lines as they are read.
-x Print commands and their arguments as they are executed.
-B the shell will perform brace expansion
-C If set, disallow existing regular files to be overwritten
by redirection of output.
-E If set, the ERR trap is inherited by shell functions.
-H Enable ! style history substitution. This flag is on
by default when the shell is interactive.
-P If set, do not resolve symbolic links when executing commands
such as cd which change the current directory.
-T If set, the DEBUG and RETURN traps are inherited by shell functions.
-- Assign any remaining arguments to the positional parameters.
If there are no remaining arguments, the positional parameters
are unset.
- Assign any remaining arguments to the positional parameters.
The -x and -v options are turned off.

genconfig.sh
set +u

事务的实现方式

您好,这份代码质量非常的高。但是事务的话,现在只能在store里面的每个接口加入db *gorm.DB的参数。不知道如何设计才会更加优雅。

Some goroutine leaks problem and Potential program crash issue

func (u *userService) List(ctx context.Context, opts metav1.ListOptions) (*v1.UserList, error) {
users, err := u.store.Users().List(ctx, opts)
if err != nil {
log.L(ctx).Errorf("list users from storage failed: %s", err.Error())
return nil, errors.WithCode(code.ErrDatabase, err.Error())
}
wg := sync.WaitGroup{}
errChan := make(chan error, 1)
finished := make(chan bool, 1)
var m sync.Map
// Improve query efficiency in parallel
for _, user := range users.Items {
wg.Add(1)
go func(user *v1.User) {
defer wg.Done()
// some cost time process
policies, err := u.store.Policies().List(ctx, user.Name, metav1.ListOptions{})
if err != nil {
errChan <- errors.WithCode(code.ErrDatabase, err.Error())
return
}
m.Store(user.ID, &v1.User{
ObjectMeta: metav1.ObjectMeta{
ID: user.ID,
InstanceID: user.InstanceID,
Name: user.Name,
Extend: user.Extend,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
},
Nickname: user.Nickname,
Email: user.Email,
Phone: user.Phone,
TotalPolicy: policies.TotalCount,
LoginedAt: user.LoginedAt,
})
}(user)
}
go func() {
wg.Wait()
close(finished)
}()
select {
case <-finished:
case err := <-errChan:
return nil, err
}
infos := make([]*v1.User, 0, len(users.Items))
for _, user := range users.Items {
info, _ := m.Load(user.ID)
infos = append(infos, info.(*v1.User))
}
log.L(ctx).Debugf("get %d users from backend storage.", len(infos))
return &v1.UserList{ListMeta: users.ListMeta, Items: infos}, nil
}

I think the design of this function errChan will have potential coroutine blocking problems, which will lead to coroutine leaks.
If more than one goroutine encounters an error, all goroutines will block except for the first error goroutine.
And here is my test demo, which confirmed my guess.

package main

import (
	"errors"
	"fmt"
	"sync"
	"time"
)

func List() error {
	wg := sync.WaitGroup{}
	errChan := make(chan error, 1)
	finished := make(chan bool, 1)

	// arr is form 1 to 10
	arr := make([]int, 10)
	for i := 0; i < len(arr); i++ {
		arr[i] = i + 1
	}

	for _, v := range arr {
		wg.Add(1)

		go func(item int) {
			defer wg.Done()

			// We assume an even number of entries will get an error
			// And We send it to errChan
			if item%2 == 0 {
				for {
					// the select is used to detect whether the coroutine is blocked here
					select {
					case errChan <- errors.New(fmt.Sprint("error message: ", item)):
						return
					case <-time.After(time.Second * 2):
						fmt.Printf("goroutine %d get an error and blocked...\n", item)
					}
				}
			}

		}(v)
	}

	go func() {
		wg.Wait()
		close(finished)
	}()

	select {
	case <-finished:
	// If we get more than one error here,
	// the goroutine that sends the error will be blocked
	case err := <-errChan:
		return err
	}

	return nil
}

func main() {
	if err := List(); err != nil {
		fmt.Println("catch error:", err)
	}

	ch := make(chan struct{})
	<-ch
}

/*
Output:
catch error: error message: 6
goroutine 10 get an error and blocked...
goroutine 8 get an error and blocked...
goroutine 4 get an error and blocked...
goroutine 8 get an error and blocked...
goroutine 10 get an error and blocked...
goroutine 4 get an error and blocked...
goroutine 10 get an error and blocked...
goroutine 8 get an error and blocked...
goroutine 4 get an error and blocked...
goroutine 4 get an error and blocked...
goroutine 8 get an error and blocked...
goroutine 10 get an error and blocked...
goroutine 10 get an error and blocked...
goroutine 8 get an error and blocked...
goroutine 4 get an error and blocked...
*/

One way to solve this problem is to set errChan's cap to the length of arrary.
And I found that go-zero is use mapreduce to solve this kind of problem about concurrent processing of list data.

And another problem in this file is that if we use the naked goroutine without 'defer recover', the whole application will panic when the naked goroutine get an unpredictable panic.
for example,

package main

import "fmt"

// sub-goroutine panic will cause the application to crash
func main() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("catch: ", err)
		}
	}()

	go func() {
		panic("sub-goroutine panic")
	}()

	ch := make(chan struct{})
	<-ch
}

/*
Output:
panic: sub-goroutine panic

goroutine 6 [running]:
main.main.func2()
        E:/Projects/go/go-cas-demos/goroutine/main.go:14 +0x27
created by main.main
        E:/Projects/go/go-cas-demos/goroutine/main.go:13 +0x4
*/

I think we can refer to the design of go-zero, and uniformly use the packaged function to start the coroutine, so as to avoid the collapse of online business.

In the past few days, I am learning the beautiful design of go-zero. If I can, I will submit a pull request to solve these problems.

iam-authz-server安装后测试授权不通过

在M1 Mac上安装了iam系统,iam-api-server测试没问题,iam-authz-server测试最终结果返回{"code":100202,"message":"Signature is invalid"},不知道哪里有问题,请帮忙看下
image
下面是系统版本:
clientVersion:
buildDate: "2023-06-26T15:11:27Z"
compiler: gc
gitCommit: 6a8f18a
gitTreeState: dirty
gitVersion: v1.1.0
goVersion: go1.20.3
platform: linux/arm64
serverVersion:
buildDate: "2023-06-26T14:52:26Z"
compiler: gc
gitCommit: 6a8f18a
gitTreeState: dirty
gitVersion: v1.1.0
goVersion: go1.20.3
platform: linux/arm64

codegen 错误

go版本:
image
操作:
在master分支最新代码
错误内容
image

请问这个是什么问题?

log日志包的扩展

使用下来发现日志包可以扩展的几个点:
1.日志包在输出到不同的地方的时候可以采用不同的writer,写到 stdout 的日志可以正常显示颜色,但是写到文本文件里的日志就不能。
我觉得可以用 zap 的tee来拼接多个core实现。
2. 现在的日志我没有找到日志分割的接口,因为是用build来创建 zap 的而不是用 zap.New 的core 来创建的,可以增加适当接口。
3. 对于日期这类我觉得也可以对外提供可选择的接口。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.