1
hijoker OP panic 的堆栈信息可以如下做
defer func() { if r := recover(); r != nil { logUtil.Error.Printf("panic, %s, collecing ends", fmt.Sprintf("%v",r)) return } }() |
2
Mohanson 2018-09-30 14:52:19 +08:00
现在日志很少会靠程序自动写了, 都是程序打印到标准输出, 然后 supervisor 或 heka 等服务捕获, 并做日志分割, 存储等功能.
|
3
heimeil 2018-09-30 15:03:19 +08:00
1. 你可以考虑一下把接口拆分得颗粒度小一点,再组合合适的功能到一起
2. 最好做到 no panic,做好错误检查比 defer recover 好得多 |
5
Immortal 2018-09-30 15:59:34 +08:00
对日志自动分片压缩的几乎没有
这个倒是真的 得自己实现了 |
6
xkeyideal 2018-09-30 16:04:57 +08:00 12
1 -> 对语言了解不深,既然是 interface,自己不实现,难道用意念编程?
2 -> panic 对应的还有个叫 recover, 参考一楼的答案,学艺不精 3 -> 日志框架,你别告诉大家说你用标准库的,现在都用第三方或自己写,有个叫 logrus 的据说挺好用 4 -> 类型信息缺失挺蛋疼,还不支持 int,int32 这些类型的自动转义,这个算个槽点 楼主应该是刚入门的级别,建议多修炼修炼,吐槽的都没到点上 你应该吐槽: 1. 为毛没有泛型? 2. 从来没见过这么垃圾的包管理? 3. 什么玩意,写个项目还要定义 gopath 这个环境变量? 4. error 处理这他妈垃圾!!! 5. 为毛编译这么快,老子都没反应过来,c++不是 make 一下可以玩一把手游的么 |
7
bonfy 2018-09-30 16:09:47 +08:00
包管理是可以吐槽
error 处理写多了,倒是没有感觉了,至少好处是每个 error 都处理,问题比以前写 Python 少多了 |
8
tourist2018 2018-09-30 16:17:07 +08:00
日志框架,默认能做到打印行号,打印时间,打印级别,控制按日志级别输出,对日志自动分片压缩的几乎没有
这个一般是第三方实现的吧 而且 go 的 log 能提供的东西已经很多了 |
10
feiyuanqiu 2018-09-30 16:22:00 +08:00
感觉最近 go 代替了 php,成为了最引战语言...是不是说明 go 最近发展势头还不错?
|
11
hcymk2 2018-09-30 16:23:43 +08:00
golang 中根据首字母的大小写来确定可以访问的权限
当初没看文档,被这个坑的不要不要的。 |
12
xkeyideal 2018-09-30 16:32:22 +08:00
@zwpaper 打印行号,打印时间,打印级别,控制按日志级别输出,对日志自动分片压缩,打印调用的堆栈信息,按照执行完整流程作用域输出等等,这些功能好像并不难实现,所以自己写个就好啦,想要啥功能自己加,还能为项目需要个性化定制
|
13
lideshun123 2018-09-30 16:35:31 +08:00
学艺不精也来喷,你看 V2 多友善
|
14
zarte 2018-09-30 16:58:47 +08:00
map slice 默认传引用这个比较坑。
|
15
janxin 2018-09-30 17:00:34 +08:00
1 无解,换个语言可破;
2 是用法你没了解; 3 这个库有的,你再找找?不过这样程序会慢,个人建议性能敏感程序不要打印文件行号信息; 4. 换个 Rust 试试? |
16
Aruforce 2018-09-30 17:01:44 +08:00 1
我想吐槽的是 p1 *P =&P{}和 p2 *P=P{}。。居然都尼玛可以。。。还有接受指针压栈的函数。。在写代码的时候 p3 P =P{}。。p3 也能直接调用。。。
综上 。。所写非所得。。。 每次写代码前都要先想下 p 到底是不是指针。。。也许是我写的太少的原因。。。 其他的泛型。。。error 处理方式。。包管理。。。还没有 ThreadLocalStorage。。其他什么的就不 BB 了。。。 |
17
jitongxi 2018-09-30 17:04:16 +08:00
楼主玩 go 一两天的经验。。。
|
18
janxin 2018-09-30 17:07:08 +08:00
@Aruforce 我想要 ThreadContext 啊,一个 ctx 显示传来传去非常蛋疼。
没 get 到第一个问题是什么问题,编译不过的吧?能否给个代码看看?另外那个真的不是传统意义上的“指针”... |
19
darrh00 2018-09-30 17:08:50 +08:00
打印行号: 默认有
打印时间 : 默认有 打印级别,控制按日志级别输出: 关于这个非常同意 Dave cheney 的观点,完全没必要分很细的日志界别 [链接]!( https://dave.cheney.net/2015/11/05/lets-talk-about-logging) 日志自动分片压缩: logrotate 写个几行配置,然后程序里响应一下 SIGHUP 信号,重新开一下日志文件,搞定。 |
20
zwpaper 2018-09-30 17:15:08 +08:00 via iPhone
@xkeyideal 自己写一个是一方面,我现在确实是改的 logrus,但是有一个好的库,还是会更好
|
21
hijoker OP @darrh00 我觉得根据日志级别控制输出是很常用的功能。。。。
还有 logrotate 这个,真心在 windows 上就不好搞了 |
23
hijoker OP @xkeyideal 你看懂了么,interface 的默认实现??
就是说几个 type struct1 struct{...} type struct2 struct{...} 都实现了某个接口,这个接口其实对于大家都是一样的,如果有个默认实现就好了,不用每个 struct 都去写同样的方法,除了 receiver 不一样之外 |
24
hijoker OP @lideshun123 请指教
|
26
silov 2018-09-30 17:20:54 +08:00
Golang 新手签到,刚刚遇到一个小坑。。。时间格式化的 Fomat、Parse 方法的格式参数。。。。竟然是那种写死的字符串。。。真是写的时候就透露着一股尴尬。。。
```golang datetime := time.Now().Format("2006-01-02 15:04:05") //后面的参数是固定的 否则将无法正常输出 ``` |
29
xkeyideal 2018-09-30 17:22:24 +08:00
@Aruforce 你这个完全是 go 好心办坏事,go 怕一些不懂或者不完全懂指针的用户指针的用法不对,造成一些他们意向不到的问题,所以将你说的这些情况都给兼容了。如果是玩过 C/C++的,根本不会有这种疑问,指针和形参还是很好区分的,另建议使用指针操作。
go 里面玩指针就按照 C/C++那套整就完全没问题,注意一下 map, slice 默认是引用传递( go 官方不承认用“引用传递”这个说法) |
30
xkeyideal 2018-09-30 17:24:32 +08:00 2
@silov 对于操作时间,给你个建议,任何时候都带上时区去计算,否则对时间强依赖的项目,死都不知道怎么死的,运维给你服务器整个 UTC 时区,你按照北京时间算
|
31
lwldcr 2018-09-30 17:25:06 +08:00
log 确实没有像 java log4j 那种功能齐备的库
不过我自己用的时候标准库的 log 上自定义部分功能+logrotate 基本满足需求了 |
33
xkeyideal 2018-09-30 17:28:40 +08:00
@hijoker 所以说你是第一天玩呢!!
你在 struct1 和 struct2 上都”继承“一个基类 struct3,然后让 struct3 去实现你想要的同一样且不需要写两次的接口不就行了么? 想玩面向对象编程那套,go 并不是不是可以,只不过现有的基础设施比较简陋,实现的面向对象不能像 C++和 Java 那么简便和高大上罢了 多看看一些开源项目对深入提升比较有好处 |
35
darrh00 2018-09-30 17:40:11 +08:00
@hijoker
光要控制日志输出,很容易, 错误信息 info 输出,调试信息 debug 输出,加一个控制开关关闭 debug 输出 分那么多 info,warn,error,fatal 就是脱裤子放*, 你真的会用那么多级别来控制程序的日志输出? 交给运维人员,运维人员会用你那么多的参数设置? windows 这个真不懂了,没有在 windows 上跑服务程序的经验。 |
36
whoami9894 2018-09-30 17:47:21 +08:00 via Android 1
哈哈我也来说一个坑:
结构体是值类型,切片是引用类型 我把一个结构体传入函数(不传指针),函数里修改结构体内容(比如 append 结构体替换原有结构体只全局可见)。如果直接修改结构体里的切片则是全局可见 |
37
RaynorGu 2018-09-30 17:49:07 +08:00
@darrh00 debug, info, warning, error 这四个级别还是要的,debug 是调试的时候打印信息,info 是线上一些做事情的日志,比如定时器啊之类的,这样查问题可以看到有没有做,warning 就是一些不是很重要的错误,error 就是重要的错误
|
38
whoami9894 2018-09-30 17:50:21 +08:00 via Android
@whoami9894
append 结构体替换原有结构体只局部可见 |
39
jinzhe 2018-09-30 18:06:03 +08:00
@silov 自己写个辅助函数转一下即可
```go // Format time.Time struct to string // MM - month - 01 // M - month - 1, single bit // DD - day - 02 // D - day 2 // YYYY - year - 2006 // YY - year - 06 // HH - 24 hours - 03 // H - 24 hours - 3 // hh - 12 hours - 03 // h - 12 hours - 3 // mm - minute - 04 // m - minute - 4 // ss - second - 05 // s - second = 5 func FormatDate(format string, t ...time.Time) string { var datetime time.Time if len(t) == 0 { datetime = time.Now() } else { datetime = t[0] } res := strings.Replace(format, "MM", datetime.Format("01"), -1) res = strings.Replace(res, "M", datetime.Format("1"), -1) res = strings.Replace(res, "DD", datetime.Format("02"), -1) res = strings.Replace(res, "D", datetime.Format("2"), -1) res = strings.Replace(res, "YYYY", datetime.Format("2006"), -1) res = strings.Replace(res, "YY", datetime.Format("06"), -1) res = strings.Replace(res, "HH", fmt.Sprintf("%02d", datetime.Hour()), -1) res = strings.Replace(res, "H", fmt.Sprintf("%d", datetime.Hour()), -1) res = strings.Replace(res, "hh", datetime.Format("03"), -1) res = strings.Replace(res, "h", datetime.Format("3"), -1) res = strings.Replace(res, "mm", datetime.Format("04"), -1) res = strings.Replace(res, "m", datetime.Format("4"), -1) res = strings.Replace(res, "ss", datetime.Format("05"), -1) res = strings.Replace(res, "s", datetime.Format("5"), -1) return res }``` |
40
bobuick 2018-09-30 18:26:40 +08:00
日志是你没用对库吧。std 里日志没有那么完整的支持,这种一般都不会在 std 里,c++, java 也是这样。
|
41
Leigg 2018-09-30 19:24:56 +08:00 via iPhone
为什么要把 panic 错误打印到日志?这说明程序写的并不够健壮,panic 错误是要爆出来给人看的,不然程序多少暗坑都不知道
|
42
reus 2018-09-30 20:49:17 +08:00 1
1, embedded field
2, runtime.Callers 3, 自己写 4, 蛋疼可能是肾亏 |
43
icris 2018-09-30 22:41:13 +08:00
@xkeyideal #6
是 interface 就得自己实现没有什么理论依据啊,连 Java 的 interface 都能放 default 了,Go 以后也不一定不加 |
45
blless 2018-10-01 09:14:45 +08:00 via Android
我也说一个…遍历一个结构体 slice 然后在循环内部取遍历出来的结构体地址…发现都是同一个地址
|
46
sxw11 2018-10-01 09:36:59 +08:00 via Android
包管理,泛型,gopath 三大坑!谁用税知道!
|
47
mosliu 2018-10-01 10:27:58 +08:00
感觉最大的坑就是包管理
现在 go mod 稍有改善的迹象 |