🇺🇦 Go for two :)
1.18K subscribers
22 photos
3 files
184 links
Telegram channel about tricks and engineering practices in the Go programming language over a cup of coffee ☕️.

author: @a_soldatenko
personal blog: https://asoldatenko.org

#golang #go #kubernetes #debugging
加入频道
Channel created
Channel photo updated
🔖 О чем канал?

3 года назад попался мне проект prometheus, и вот пытался я его запустить все дела. Как обычно, начинаешь устанавливать, проходить всякий getting-started, потом … часа через 2 ты уже дебажишь исходный код и пытаешься отправить свой патч на Github.
Так я узнал про язык программирования Go! На этой приятной ноте, предлагаю Вам подписаться на мой канал чтобы быть в курсе того над чем я работаю и прочитать что-то интересное (не ссылку и не копипаст) о новом, но довольно популярном языке программирования Go за чашечкой кофе :)

P.S. В комментариях можно поделиться своей историей, о том как Вы начали писать на Go и почему?
P.P.S. Лого канала взял у жены Rob Pike -> Renee French https://www.instagram.com/reneefrench/ :)
🐛Дебажим код написанный на Go


Да код на Go можно и нужно дебажить. Часто сталкиваюсь в разных командах, как разработчики, до сих пор в 2019 году! дебажат принтами :)

Delve - дебаггер который я обычно использую каждый день. Если открыть документацию, она мягко говоря не идеальная.


Установить можно так: go get -u github.com/go-delve/delve/cmd/dlv
Чаще всего я использую dlv debug <имя пакета>.

dlv debug github.com/andriisoldatenko/go-blog

Либо

dlv debug main.go
(dlv) breakpoint main.go:1
(dlv) continue

После того как установили breakpoint, можно нажать continue и программа остановится там где нужно и так далее. Также есть shortcuts (b, c, l и так далее).
🔨 Note #3 Настраиваем дебаггер

Сегодня наткнулся на то, что print в режиме дебаггера, не показывает длинные строки.

> main.main() ./main.go:7 (PC: 0x10b08d4)
2:
3: import "fmt"
4:
5: func main() {
6: v1 := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
=> 7: fmt.Println(v1)
8: }
(dlv) p v1
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...+2 more"

(dlv) config -list
aliases map
substitute-path
max-string-len <not defined>
max-array-values <not defined>
show-location-expr false

(dlv) config max-string-len 1000
(dlv) p v1
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

Теперь можно напечатать длинную строку.
Forwarded from Go Library
Writing and Optimizing Go code

This document outlines best practices for writing high-performance Go code.

https://github.com/dgryski/go-perfbook/blob/master/performance.md
Вот как нужно делать программу для конференции!
GoCon Canada -> https://play.golang.org/p/dSlNFqsiKKl
Наверное одна из самых лучших статей, которые попадались мне на тему как писать хороший Git Commit Message https://chris.beams.io/posts/git-commit/
COME ON SHOW US THE REGULAR EXPRESSION
или как Cloudflare обещает показать регулярное выражение ...
https://blog.cloudflare.com/cloudflare-outage/
Ответ очевидный :)
Брайн Керниган рассказывает как придумали название "grep" ->
eсли кратко то:
g/re/p
если догадались почему именно так, либо можно посмотреть видос:
https://www.youtube.com/watch?v=NTfOnGZUZDk
Монстры внутри sync.Locker
GoGoConf 2019: Roberto Clapis
https://www.youtube.com/watch?v=ok4NEfqAXb0
Note #4 Дебажим приложение на Go в докере 🐳

Итак нам понадобится:
- прямые руки и тазик с предустановленным докером

$ cat Dockerfile
FROM golang:1.13

WORKDIR /go/src/app
COPY . .

RUN go get -u github.com/go-delve/delve/cmd/dlv

CMD ["app"]


$ docker build -t my-golang-app .

# Это всего лишь один из вариантов, иногда нужно вместо bash сразу dlv запускать и так далее
$ docker run -it --rm my-golang-app bash

$ root@03c1977b1063:/go/src/app# dlv main.go
Error: unknown command "main.go" for "dlv"
Run 'dlv --help' for usage.
root@03c1977b1063:/go/src/app# dlv debug main.go
could not launch process: fork/exec /go/src/app/__debug_bin: operation not permitted

OOps...

Итак добавим параметры:

$ docker run -it --rm --security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE my-golang-app bash

И вуаля 🎉
$ root@7dc3a7e8b3fc:/go/src/app# dlv debug main.go
Type 'help' for list of commands.
(dlv)

P.S. опять же этот же трюк можно использовать с docker-compose/ либо с multi-stage билдами. Если интересно как дебажить multi-stage билды на Го просьба поставить “+” в комментариях или кинуть помидором 🍅.
Note #5 Дебажим приложения в multi-stage докере 🐳

Давайте представим, что на проде у вас есть микросервис, каждый из которых живет в своем Dockerfile и естественно, как у всех взрослых дядь - это multi-stage Dockerfile. Более подробно о multi-stage можно прочитать в доках ( https://docs.docker.com/develop/develop-images/multistage-build/), если лень - то этопросто Dockerfile у которого есть 2 FROM ключевых слова и в мы что-то копируем из одного в другой слой.

Итак приступим 🐎:
docker build -t goapp:latest .
Sending build context to Docker daemon 22.53kB
Step 1/7 : FROM golang AS builder
...
Successfully tagged goapp:latest


Каждый день нам нужно разрабатывать и дебажить это приложение: внимательный читатель может предложить установить дебаггер внутри одного из слоев. Итак добавим что-то вроде:


--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,5 @@
FROM golang AS builder
+RUN go get -u github.com/go-delve/delve/cmd/dlv
ADD . /src
RUN cd /src && go build -o goapp


И затем запустим что-то вроде этого:

➜  debug-multi-stage-docker-and-go docker run -it --entrypoint=dlv goapp
docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"dlv\": executable file not found in $PATH": unknown.


И вот незадача, та же история будет если у вас docker-compose для локальной разработки или что-то еще. Как быть)
Есть замечательный флаг --target у docker build!

docker build --target builder -t goapp:latest .
docker run -it goapp sh
# dlv debug main.go
could not launch process: fork/exec /src/__debug_bin: operation not permitted

А как пофиксить это ☝️, читай мой прошлый пост https://yangx.top/golang_for_two/20 )

И Вуаля! Огромный Плюс ⚡️ данного подхода лично для меня, отсутствие Dockerfile-dev и вариантов.

P.S. Если же у тебя docker-compose, то в своем docker-compose.override.yml можно написать так:
version: "3.4"
services:
app:
image: goapp:dev
build:
context: .
dockerfile: Dockerfile
target: builder

🎉💥🎉