ΠΠΎΠ²Π°Ρ Π²Π΅ΡΡΠΈΡ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ ΠΏΡΠΎΠ΅ΠΊΡΠ°
ΠΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π½ΡΠΉ Π½ΠΈΠΆΠ΅ ΡΠ°Π±Π»ΠΎΠ½ ΡΠ΅ΡΠ²Π΅ΡΠ° Π½Π° Golang Π±ΡΠ» ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²Π»Π΅Π½ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π·Π½Π°Π½ΠΈΠΉ Π²Π½ΡΡΡΠΈ Π½Π°ΡΠ΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ. ΠΡΠ½ΠΎΠ²Π½Π°Ρ ΡΠ΅Π»Ρ ΡΠ°Π±Π»ΠΎΠ½Π°, ΠΊΡΠΎΠΌΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ - ΡΡΠΎ ΡΠ½ΠΈΠ·ΠΈΡΡ Π²ΡΠ΅ΠΌΡ Π½Π° ΠΏΡΠΎΡΠΎΡΠΈΠΏΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅Π±ΠΎΠ»ΡΡΠΈΡ ΡΠ΅ΡΠ²Π΅ΡΠ½ΡΡ Π·Π°Π΄Π°Ρ Π½Π° Go.
Π¨Π°Π±Π»ΠΎΠ½ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ:
- ΠΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° HTTP ΡΠ΅ΡΠ²Π΅ΡΠ° ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠΌΠ°Π½Π΄Π½ΡΡ ΡΡΡΠΎΠΊΡ github.com/urfave/cli
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΡΠ΅ΡΠ²Π΅ΡΠ° ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠΉ ΡΠ°ΠΉΠ» github.com/sasbury/mini
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² TLS HTTP ΡΠ΅ΡΠ²Π΅ΡΠ°
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΡΠΎΡΡΠ΅ΡΠ° ΠΈ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ HTTP ΠΈ prof-ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² github.com/gorilla/mux
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΡΡΠΎΠ²Π½Π΅ΠΉ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π±Π΅Π· ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ° github.com/hashicorp/logutils
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ HTTP ΡΡΠ°ΡΠΈΠΊΠ° Π±Π΅Π· ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ°
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ Π² HTTP response Π±Π΅Π· ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ°
- HTTP Basic Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ
- MS AD Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ gopkg.in/korylprince/go-ad-auth.v2
- JSON Web Token github.com/dgrijalva/jwt-go
- ΠΠ°ΠΏΡΡΠΊ ΡΠ΅ΡΠ²Π΅ΡΠ° Ρ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ΠΌ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° Π² ΠΊΠ°Π½Π°Π» ΠΎΡΠΈΠ±ΠΎΠΊ
- ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° Π΄Π»Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠΉ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΈ ΡΠ²ΡΠ·Π°Π½Π½ΡΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΊΠ°ΡΡΠΎΠΌΠ½ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ github.com/pkg/errors
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΠΊΠ°ΡΡΠΎΠΌΠ½ΠΎΠ³ΠΎ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ
- Π‘Π±ΠΎΡΠΊΠ° Ρ Π²Π½Π΅Π΄ΡΠ΅Π½ΠΈΠ΅ΠΌ Π²Π΅ΡΡΠΈΠΈ, Π΄Π°ΡΡ ΡΠ±ΠΎΡΠΊΠΈ ΠΈ commit
Π‘ΡΡΠ»ΠΊΠ° Π½Π° ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ ΠΏΡΠΎΠ΅ΠΊΡΠ°.
Π ΡΠΎΡΡΠ°Π² ΡΠ°Π±Π»ΠΎΠ½Π° Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ HTTP ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ²:
- POST /echo - ΡΡΠ°Π½ΡΠ»ΡΡΠΈΡ request HTTP ΠΈ body Π² response
- POST /signin - Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ JSON Web Token Π² Cookie
- POST /refresh - ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ JSON Web Token Π² Cookie
- POST /httplog - Π½Π°ΡΡΡΠΎΠΉΠΊΠ° Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ HTTP ΡΡΠ°ΡΠΈΠΊΠ°
- POST /httperrlog - Π½Π°ΡΡΡΠΎΠΉΠΊΠ° Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ Π² HTTP response
- POST /loglevel - Π½Π°ΡΡΡΠΎΠΉΠΊΠ° ΡΡΠΎΠ²Π½Π΅ΠΉ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ DEBUG, INFO, ERROR
ΠΠΎΠ΄Ρ ΠΎΠ΄ ΠΊ ΡΠΏΡΠΎΡΠ΅Π½ΠΈΡ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ HTTP ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΡΠ°Π±Π»ΠΎΠ½Π° ΠΎΠΏΠΈΡΠ°Π½ Π² ΡΡΠ°ΡΡΠ΅ Π£ΠΏΡΠΎΡΠ°Π΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠ΅ HTTP ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π½Π° Golang
- ΠΡΠ΅Π΄ΡΡΡΠΎΡΠΈΡ
- ΠΠ΅ΡΠ΅Π΄Π°ΡΠ° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΡΠ΅ΡΠ²Π΅ΡΡ
2.2. ΠΠΎΠΌΠ°Π½Π΄Π½Π°Ρ ΡΡΡΠΎΠΊΠ°
2.3. ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠΉ ΡΠ°ΠΉΠ» - Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅, Π·Π°ΠΏΡΡΠΊ ΠΈ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΡΠ΅ΡΠ²Π΅ΡΠ°
3.1. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ daemon ΠΈ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
3.2. ΠΠ°ΠΏΡΡΠΊ daemon ΠΈ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
3.3. ΠΡΡΠ°Π½ΠΎΠ²ΠΊΠ° daemon ΠΈ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ² - ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΎΡΠΈΠ±ΠΎΠΊ
4.1. ΠΠ°ΡΡΠΎΠΌΠ½Π°Ρ ΡΡΡΡΠΊΡΡΡΠ° ΠΎΡΠΈΠ±ΠΊΠΈ
4.2. Π€ΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ°ΡΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ
4.3. Π Π΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ
4.4. ΠΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΎΡΠΈΠ±ΠΎΠΊ - ΠΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
5.1. ΠΡΠ΄Π° Π»ΠΎΠ³ΠΈΡΡΠ΅ΠΌ
5.2. Π€ΠΎΡΠΌΠ°Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ
5.3. ΠΠ°ΠΊ Π»ΠΎΠ³ΠΈΡΡΠ΅ΠΌ
5.4. ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ HTTP ΡΡΠ°ΡΠΈΠΊΠ° - ΠΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ
- ΠΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΡ ΠΊΠΎΠ΄Π° ΠΈ ΡΠ±ΠΎΡΠΊΠ°
7.1. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ go mod
7.2. Π‘Π±ΠΎΡΠΊΠ° ΠΊΠΎΠ΄Π°
Π Ρ ΠΎΠ΄Π΅ Π²Π½Π΅Π΄ΡΠ΅Π½ΠΈΡ 1Π‘:ERP, ΠΏΠΎΡΠ²ΠΈΠ»Π°ΡΡ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½Π°Ρ Π·Π°Π΄Π°ΡΠ° - ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ 1Π‘ Ρ ΡΠΈΠ½ΠΎΠΉ IBM MQ. ΠΠ»ΡΡΠ΅Π²ΡΠΌΠΈ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡΠΌΠΈ Π² ΡΠ°ΡΡΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ Ρ IBM MQ Π±ΡΠ»ΠΈ:
- ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΡΠ»ΠΎΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ ΠΊ IBM MQ (ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ΅, ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ΅, Π²ΡΠ΅ΠΌΡ ΠΏΡΠΎΡΡΠΎΡ)
- Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π½Π° ΡΠ΅Π·Π΅ΡΠ²Π½ΡΠΉ ΡΠ·Π΅Π» IBM MQ ΠΏΡΠΈ ΡΠ±ΠΎΠ΅ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ ΡΠ·Π»Π°
- ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΆΠΈΠΌΠ° ΠΏΡΠΈ ΡΠ°Π±ΠΎΡΠ΅ Ρ IBM MQ (SYNCPOINT)
ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π±ΡΠ»ΠΈ Π²ΡΠ΄Π²ΠΈΠ½ΡΡΡ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΠΊ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ΅ XML ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ:
- Π½ΠΎΡΠΌΠ°Π»ΠΈΠ·Π°ΡΠΈΡ (ΠΊΠ°Π½ΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ) ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΏΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΡ RFC 3076
- ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠ΅ΡΠΎΠΊ ΡΠ΅Π»ΠΎΡΡΠ½ΠΎΡΡΠΈ Π΄Π»Ρ Π²Π΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΏΠΎ ΠΊΠ°ΡΡΠΎΠΌΠ½ΠΎΠΌΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΡ HMAC Ρ Ρ ΡΡ-ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ ΠΠΠ‘Π’-34.11.94
- ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΡΠΌ ΠΊΡΡΠ΅ΠΌ ΡΠ΅ΠΊΡΠ΅ΡΠ½ΡΡ ΠΊΠ»ΡΡΠ΅ΠΉ Π΄Π»Ρ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ HMAC
Π‘ΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠ³ΠΎ Π°Π΄Π°ΠΏΡΠ΅ΡΠ° Π² 1C ΠΊ IBM MQ Π½Π΅ Π±ΡΠ»ΠΎ. Π‘ΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠΉ REST API ΠΊ IBM MQ Π½Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΈΠ» ΠΏΠΎΠ΄ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ.
ΠΠ΄Π°ΠΏΡΠ΅Ρ 1C ΠΊ IBM MQ Π±ΡΠ» ΡΡΠΏΠ΅ΡΠ½ΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ°Π½ Π½Π° Go Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ IBM MQ. ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΎΡΠ»ΠΈΡΠ°Π΅ΡΡΡ Π½Π΅ΠΏΠ»ΠΎΡ ΠΎΠΉ ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΠΎΡΡΡΡ, ΡΡΠΎ ΠΈ Π½Π΅ ΡΠ΄ΠΈΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½Π° Π½Π°ΠΏΠΈΡΠ°Π½Π° Π² Π²ΠΈΠ΄Π΅ "ΠΎΠ±Π΅ΡΡΠΊΠΈ" Π½Π°Π΄ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΉ C Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΎΠΉ. ΠΠ° ΠΏΠΎΠ»Π³ΠΎΠ΄Π° ΡΠ°Π±ΠΎΡΡ Ρ Π½Π΅ΠΉ Π±ΡΠ»ΠΎ Π·Π°ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΎ Π²ΡΠ΅Π³ΠΎ 2 Π±Π°Π³Π° Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΎΠΉ ΡΠ»Π°ΠΉΡΠΎΠ² [].
ΠΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π½ΡΠΉ Π² ΡΡΠ°ΡΡΠ΅ ΡΠ°Π±Π»ΠΎΠ½ backend ΡΠ΅ΡΠ²Π΅ΡΠ°, ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ±ΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠΏΡΡΠ°.
ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° Π°Π΄Π°ΠΏΡΠ΅ΡΠ° 1Π‘ ΠΊ IBM MQ ΡΠΊΡΡΠΏΠ½Π΅Π½ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π½Π° ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΡΠΈΡΡΠ½ΠΊΠ΅.
ΠΡΠ΅ ΡΡΠ²ΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅, Ρ ΡΠΎΡΠΊΠΈ Π·ΡΠ΅Π½ΠΈΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ, ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠΌΠ°Π½Π΄Π½ΡΡ ΡΡΡΠΎΠΊΡ. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° github.com/urfave/cli. Π‘ΠΏΠΈΡΠΎΠΊ ΠΎΡΠ½ΠΎΠ²Π½ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ²:
--httpconfig value, --httpcfg value HTTP Config file name
--listenstring value, -l value Listen string in format <host>:<port>
--httpuser value, --httpu value User name for access to HTTP server
--httppassword value, --httppwd value User password for access to HTTP server
--jwtkey value, --jwtk value JSON web token secret key
--debug value, -d value Debug mode: DEBUG, INFO, ERROR
--logfile value, --log value Log file name
ΠΠ»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° github.com/sasbury/mini. Π‘ΠΏΠΈΡΠΎΠΊ ΡΠΈΠΏΠΎΠ²ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ², Π²ΠΊΠ»ΡΡΠ΅Π½Π½ΡΡ Π² ΡΠ°Π±Π»ΠΎΠ½:
[HTTP_SERVER]
ReadTimeout = 6000 // HTTP read timeout duration in sec - default 60 sec
WriteTimeout = 6000 // HTTP write timeout duration in sec - default 60 sec
IdleTimeout = 6000 // HTTP idle timeout duration in sec - default 60 sec
MaxHeaderBytes = 262144 // HTTP max header bytes - default 1 MB
MaxBodyBytes = 1048576 // HTTP max body bytes - default 0 - unlimited
UseProfile = false // use Go profiling
ShutdownTimeout = 30 // service shutdown timeout in sec - default 30 sec
[TLS]
UseTLS = false // use SSL
UseHSTS = false // use HTTP Strict Transport Security
TLSΠ‘ertFile = certs/server.pem // TLS Certificate file name
TLSKeyFile = certs/server.key // TLS Private key file name
TLSMinVersion = VersionTLS10 // TLS min version VersionTLS13, VersionTLS12, VersionTLS11, VersionTLS10, VersionSSL30
TLSMaxVersion = VersionTLS12 // TLS max version VersionTLS13, VersionTLS12, VersionTLS11, VersionTLS10, VersionSSL30
[JWT]
UseJWT = false // use JSON web token (JWT)
JWTExpiresAt = 20000 // JWT expiry time in seconds - 0 without restriction
[AUTHENTIFICATION]
AuthType = INTERNAL // Autehtification type NONE | INTERNAL | MSAD
MSADServer = company.com // MS Active Directory server
MSADPort = 389 // MS Active Directory Port
MSADBaseDN = OU=, DC=, DC= // MS Active Directory BaseDN
MSADSecurity = SecurityNone // MS Active Directory Security: SecurityNone, SecurityTLS, SecurityStartTLS
[LOG]
HTTPLog = false // Log HTTP traffic
HTTPLogType = INREQ // HTTP trafic log mode INREQ | OUTREQ | INRESP | OUTRESP | BODY
HTTPLogFileName = ./httplog/http%s.log // HTTP log file
HTTPErrLog = HEADER | BODY // Log error into HTTP response header and body
ΠΠ° ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΡΠΈΡΡΠ½ΠΊΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° ΡΠΏΡΠΎΡΠ΅Π½Π½Π°Ρ UML Π΄ΠΈΠ°Π³ΡΠ°ΠΌΠΌΠ° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ Π·Π°ΠΏΡΡΠΊΠ° ΠΈ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ°.
ΠΠ»Ρ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΠΈΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ, Π·Π°ΠΏΡΡΠΊΠ° ΠΈ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ daemon. Π Π΅Π³ΠΎ Π·Π°Π΄Π°ΡΠΈ Π²Ρ ΠΎΠ΄ΠΈΡ:
- ΡΡΠΈΡΡΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°
- Π½Π°ΡΡΡΠΎΠΉΠΊΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
- ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° context.Context
- ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»ΠΎΠ² ΠΎΡΠΈΠ±ΠΎΠΊ Π΄Π»Ρ ΠΎΠ±ΡΠ°ΡΠ½ΠΎΠΉ ΡΠ²ΡΠ·ΠΈ Ρ ΡΠ΅ΡΠ²ΠΈΡΠ°ΠΌΠΈ
- ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΡΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
- ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΠΉ Π·Π°ΠΏΡΡΠΊ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
- ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΠΉ ΠΈ/ΠΈΠ»ΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ ΠΎΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
- ΠΊΠΎΡΡΠ΅ΠΊΡΠ½Π°Ρ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
Π ΠΎΠ±ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅, ΡΠ΅ΡΠ²ΠΈΡΡ ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΠΈ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°ΡΡΡΡ ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ daemon.
ΠΡΠ»ΠΈ Π΅ΡΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ
ΡΠ΅ΡΠ²ΠΈΡΠ°Ρ
, ΡΠΎ daemon Π½Π΅ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ.
ΠΡΠ»ΠΈ ΡΠ΅ΡΠ²ΠΈΡ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Π² ΡΠΎΠ½Π΅, ΡΠΎ Π² daemon Π΄Π»Ρ Π½Π΅Π³ΠΎ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΊΠ°Π½Π°Π» ΠΎΡΠΈΠ±ΠΎΠΊ:
httpserverErrCh: make(chan error, 1), // ΠΊΠ°Π½Π°Π» ΠΎΡΠΈΠ±ΠΎΠΊ HTTP ΡΠ΅ΡΠ²Π΅ΡΠ°
ΠΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ΅ΡΠ²ΠΈΡΠ°, Π΅ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ:
- ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ daemon - ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π² ΡΠ΅ΡΠ²ΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΎ Π·Π°ΠΊΡΡΡΠΈΠΈ
- ΠΊΠ°Π½Π°Π» ΠΎΡΠΈΠ±ΠΎΠΊ - ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° ΠΈΠ· ΡΠ΅ΡΠ²ΠΈΡΠ° Π² daemon ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΎ ΠΊΡΠΈΡΠΈΡΠ½ΠΎΠΉ ΠΎΡΠΈΠ±ΠΊΠ΅
- ΡΡΡΡΠΊΡΡΡΡ Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΡΠΌΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ ΡΠ΅ΡΠ²ΠΈΡΠ°
ΠΡΠΈΠΌΠ΅ΡΡ Π·Π°Π΄Π°Ρ ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²:
- ΠΠ»Ρ ΡΠ΅ΡΠ²ΠΈΡΠ° ΡΠ°Π±ΠΎΡΡ Ρ IBM MQ:
- ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ Π²Ρ ΠΎΠ΄Π½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ
- ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ°
- Π΄Π΅Π»Π°Π΅ΡΡΡ ΡΠ΅ΡΡΠΎΠ²ΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊ ΠΊΠ»Π°ΡΡΠ΅ΡΡ IBM MQ, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΡΡ ΠΊΠ°ΠΊΠΎΠΉ ΠΈΠ· ΡΠ·Π»ΠΎΠ² ΠΊΠ»Π°ΡΡΠ΅ΡΠ° ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ°Π±ΠΎΡΠΈΠΌ, Π° ΠΊΠ°ΠΊΠΎΠΉ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² ΡΠ΅Π·Π΅ΡΠ²Π΅
- ΠΎΡΠΊΡΡΠ²Π°Π΅ΡΡΡ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΠΏΡΠ» ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ ΠΊ IBM MQ
- ΠΠ»Ρ ΡΠ΅ΡΠ²ΠΈΡΠ° ΡΠ°Π±ΠΎΡΡ Ρ PostgreSQL:
- ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ Π²Ρ ΠΎΠ΄Π½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ
- ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ°
- Π΄Π΅Π»Π°Π΅ΡΡΡ ΡΠ΅ΡΡΠΎΠ²ΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
- ΠΏΠ°ΡΡΡΡΡΡ, ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠ΅, SQL ΠΊΠΎΠΌΠ°Π½Π΄Ρ
- ΠΠ»Ρ ΡΠ΅ΡΠ²ΠΈΡΠ° ΠΊΠ΅ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ JSON Π² BoltDB:
- ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ Π²Ρ ΠΎΠ΄Π½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ
- ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ°
- ΠΎΡΠΊΡΡΠ²Π°Π΅ΡΡΡ ΡΠ°ΠΉΠ» BoltDB Π½Π° Π·Π°ΠΏΠΈΡΡ
- ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΡΡΠΈΡΡΠ²Π°Π½ΠΈΠ΅ Π·Π°ΠΊΠ΅ΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΠΊΠ»ΡΡΠ΅ΠΉ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ Π²Π°Π»ΠΈΠ΄Π½ΠΎΡΡΡ ΠΊΡΡΠ° (Π΄Π°Π½Π½ΡΠ΅ ΠΌΠΎΠ³Π»ΠΈ ΠΏΠΎΠΌΠ΅Π½ΡΡΡΡΡ Π² ΠΠ PostgreSQL). ΠΡΠ° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΏΠ΅ΡΠ΅Π½Π΅ΡΠ΅Π½Π° Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΡΠΎΠ½ΠΎΠ²ΡΠΉ ΠΏΡΠΎΡΠ΅ΡΡ, ΡΡΠΎΠ±Ρ ΡΠΎΠΊΡΠ°ΡΠΈΡΡ Π²ΡΠ΅ΠΌΡ ΡΡΠ°ΡΡΠ° ΡΠ΅ΡΠ²Π΅ΡΠ° (Π² Ρ ΠΎΠ΄Π΅ ΡΠ΅ΡΡΠ° Π½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ BoltDB ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ 150 ΠΠ±Π°ΠΉΡ ΡΡ ΠΎΠ΄ΠΈΡ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ 2 ΠΌΠΈΠ½ΡΡΡ Π² 64 ΠΏΠΎΡΠΎΠΊΠ° ΠΏΡΠΈ ΡΡΠ»ΠΎΠ²ΠΈΠΈ, ΡΡΠΎ BoltDB ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½Π° Π½Π° NVMe Π΄ΠΈΡΠΊΠ΅ ΡΠΎ ΡΡΠ΅Π΄Π½ΠΈΠΌ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΎΡΠΊΠ»ΠΈΠΊΠ° 0.03 ms).
- ΠΠ»Ρ HTTP ΡΠ΅ΡΠ²Π΅ΡΠ°:
- ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ Π²Ρ ΠΎΠ΄Π½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ
- ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ°
- ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΠΈ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΡΡΡ http.server
- ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ TCP Π»ΠΈΡΡΠ΅Π½Π΅Ρ
- Π½Π°ΡΡΡΠ°ΠΈΠ²Π°ΡΡΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ TLS
- ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΡΠΎΡΡΠ΅Ρ
- ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΡΡΡΡ HTTP ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ
- ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΡΡΡΡ pprof ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ
ΠΠ°ΠΏΡΡΠΊ daemon Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΡΠΊΠΎΠΎΡΠ΄ΠΈΠ½ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌ Π·Π°ΠΏΡΡΠΊΠ΅ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ².
Π’Π°ΠΊ ΠΊΠ°ΠΊ Π²ΡΠ΅ ΡΠ΅ΡΠ²ΠΈΡΡ ΡΠΆΠ΅ Π±ΡΠ»ΠΈ ΡΠΎΠ·Π΄Π°Π½Ρ ΡΠ°Π½Π΅Π΅, ΡΠΎ Π·Π°ΠΏΡΡΠΊ ΡΠ΅ΡΠ²ΠΈΡΠ° - ΡΡΠΎ, ΠΎΠ±ΡΡΠ½ΠΎ, Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π»ΠΈΡΡΠ΅Π½Π΅ΡΠ° ΠΈΠ»ΠΈ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠ»Π°Π³Π°, ΡΠ°Π·ΡΠ΅ΡΠ°ΡΡΠ΅Π³ΠΎ Π½Π°ΡΠ°ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ.
ΠΠ»Ρ Π·Π°ΠΏΡΡΠΊΠ° ΡΠ΅ΡΠ²ΠΈΡΠΎΠ² Π² ΡΠΎΠ½Π΅, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π°Π½ΠΎΠ½ΠΈΠΌΠ½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠΎΠΌ Π² ΠΊΠ°Π½Π°Π» ΠΎΡΠΈΠ±ΠΎΠΊ. ΠΡΠΈΠΌΠ΅Ρ, Π·Π°ΠΏΡΡΠΊΠ° HTTP ΡΠ΅ΡΠ²Π΅ΡΠ°
go func() { httpserverErrCh <- d.httpserver.Run() }()
ΠΠΎΡΠ»Π΅ Π·Π°ΠΏΡΡΠΊΠ° ΡΠ΅ΡΠ²ΠΈΡΠΎΠ², daemon ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π½Π° ΠΎΡΠ½ΠΎΠ²Π½ΡΠ΅ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΡ ΠΈ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ΠΈΡ Π² ΡΠ΅ΠΆΠΈΠΌ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ ΡΠΈΠ³Π½Π°Π»ΠΎΠ² ΠΈΠ»ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ° Π² ΠΊΠ°Π½Π°Π»Ρ ΠΎΡΠΈΠ±ΠΎΠΊ ΠΎΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ².
ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ daemon ΠΎΡΠΈΠ±ΠΊΠΈ ΠΎΡ ΡΠ΅ΡΠ²ΠΈΡΠ°, ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ ΠΈΠ· ΡΠ΅ΡΠ²ΠΈΡΠΎΠ² Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ ΡΠ°Π±ΠΎΡΡ. ΠΠ΄Π΅ΡΡ Π»ΠΎΠ³ΠΈΠΊΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΌΠΎΠΆΠ΅Ρ ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ, ΠΎΡ ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ (ΠΊΠ°ΠΊ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π½ΠΈΠΆΠ΅) Π΄ΠΎ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΡΡΠΊΠ° ΡΠ±ΠΎΠΉΠ½ΠΎΠ³ΠΎ ΡΠ΅ΡΠ²ΠΈΡΠ°.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠ΅ΡΠ²Π΅Ρ IBM MQ ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ Π½Π΅Π΄ΠΎΡΡΡΠΏΠ΅Π½, ΡΠΎ daemon ΠΏΡΠΎΠ±ΡΠ΅Ρ ΠΏΠ΅ΡΠ΅ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ΅ΡΠ²ΠΈΡ Π½Π° ΡΠ΅Π·Π΅ΡΠ²Π½ΠΎΠΌ ΡΠ΅ΡΠ²Π΅ΡΠ΅ IBM MQ ΠΈ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ.
syscalCh := make(chan os.Signal, 1) // ΠΊΠ°Π½Π°Π» ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ
ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΠΉ
signal.Notify(syscalCh, syscall.SIGINT, syscall.SIGTERM)
// ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΡ ΠΈΠ»ΠΈ Π²ΠΎΠ·Π²ΡΠ°Ρ Π² ΠΊΠ°Π½Π°Π» ΠΎΡΠΈΠ±ΠΎΠΊ
select {
case s := <-syscalCh: // ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ΅ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΠ΅
mylog.PrintfInfoMsg("Exiting, got signal", s)
d.Shutdown() // ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ daemon
return nil
case err := <-d.httpserverErrCh: // Π²ΠΎΠ·Π²ΡΠ°Ρ ΠΎΡ HTTP ΡΠ΅ΡΠ²Π΅ΡΠ° Π² ΠΊΠ°Π½Π°Π» ΠΎΡΠΈΠ±ΠΎΠΊ
mylog.PrintfErrorInfo(err) // Π»ΠΎΠ³ΠΈΡΡΠ΅ΠΌ ΠΎΡΠΈΠ±ΠΊΡ
d.Shutdown() // ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ daemon
return err
}
Π Π·Π°ΠΏΡΡΠΊ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ², ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΡ Π² ΡΠΎΠ½Π΅, Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΡΡΡ Π°Π½ΠΎΠ½ΠΈΠΌΠ½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅ ΠΏΠ°Π½ΠΈΠΊΠΈ (ΠΏΡΠΈΠΌΠ΅Ρ Π½ΠΈΠΆΠ΅). ΠΡΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ΅ ΠΏΠ°Π½ΠΈΠΊΠΈ, ΠΎΡΠΈΠ±ΠΊΠ° Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ Π² ΠΊΠ°Π½Π°Π» ΠΎΡΠΈΠ±ΠΎΠΊ Π΄Π»Ρ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ daemon.
func (s *Server) Run() error {
defer func() {
var myerr error
r := recover()
if r != nil {
msg := "Recover from panic"
switch t := r.(type) {
case string:
myerr = myerror.New("8888", msg, t)
case error:
myerr = myerror.WithCause("8888", msg, t)
default:
myerr = myerror.New("8888", msg)
}
mylog.PrintfErrorInfo(myerr) // Π»ΠΎΠ³ΠΈΡΡΠ΅ΠΌ ΠΎΡΠΈΠ±ΠΊΡ
s.errCh <- myerr // ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ ΠΎΡΠΈΠ±ΠΊΡ Π² ΠΊΠ°Π½Π°Π» Π΄Π»Ρ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ daemon
}
}()
// ΠΠ°ΠΏΡΡΠΊ ΡΠ΅ΡΠ²Π΅ΡΠ°
}
ΠΡΡΠ°Π½ΠΎΠ²ΠΊΠ° daemon Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΡΠΊΠΎΠΎΡΠ΄ΠΈΠ½ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠ΅ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ² ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ Π·Π°ΠΊΡΡΡΠΈΠΈ ΠΊΠΎΡΠ½Π΅Π²ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°.
ΠΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΡΠ΅ΡΠ²ΠΈΡΠΎΠ², ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΡ Π² ΡΠΎΠ½Π΅, ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠΎ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌΡ ΡΡΠ΅Π½Π°ΡΠΈΡ:
- ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ ΡΠ°ΠΉΠΌΠ΅Ρ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ ΡΡΠΏΠ΅ΡΠ½ΠΎΠΉ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ (ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ShutdownTimeout Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅)
- Π·Π°ΠΊΡΡΠ²Π°Π΅ΡΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΡΠ΅ΡΠ²ΠΈΡΠ°
- Π² Π·Π°Π΄Π°ΡΡ Π²ΡΠ΅Ρ
ΡΠ΅ΡΠ²ΠΈΡΠΎΠ² Π²Ρ
ΠΎΠ΄ΠΈΡ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½Π°Ρ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π°ΠΊΡΠΈΠ²Π½ΠΎΠΉ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΈ Π·Π°ΠΊΡΡΡΠΈΠΈ ΠΈΡ
ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°. ΠΠ° ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΡΠ΅ΡΠ²ΠΈΡΠ° IBM MQ ΡΡΠΎ:
- ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ΅ΠΊΡΡΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ
- Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΡΠΊΡΡΡΡΡ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΉ
- Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅Π½ΠΈΠ΅ Π°ΠΊΡΠΈΠ²Π½ΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ Π² ΠΏΡΠ»
- Π·Π°ΠΊΡΡΡΠΈΠ΅ ΠΎΡΠΊΡΡΡΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Π΅ΠΉ
- Π·Π°ΠΊΡΡΡΠΈΠ΅ ΠΏΡΠ»Π° Π°ΠΊΡΠΈΠ²Π½ΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ ΠΊ IBM MQ
- ΠΏΠΎΡΠ»Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎΠΉ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²ΠΈΡ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² ΠΊΠ°Π½Π°Π» stopCh
ΠΠ»Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠΉ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ² ΠΏΡΠΈ Π·Π°ΠΊΡΡΡΠΈΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠ°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄:
- Π² ΠΊΠΎΡΠ½Π΅Π²ΡΡ ΡΠΈΠΊΠ»Π°Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΡΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°. ΠΡΠ»ΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π·Π°ΠΊΡΡΡ, ΡΠΎ ΠΎΡΠ΅ΡΠ΅Π΄Π½ΡΡ ΠΈΡΠ΅ΡΠ°ΡΠΈΡ Π½Π΅ Π½Π°ΡΠΈΠ½Π°ΡΡ ΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡ ΡΠ΅ΡΡΡΡΡ
- Π² ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°Ρ , Π² Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΡ ΠΌΠ΅ΡΡΠ°Ρ , Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°, Π΅ΡΠ»ΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π·Π°ΠΊΡΡΡ, ΡΠΎ Π½Π΅ Π½Π°ΡΠΈΠ½Π°ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ
for {
select {
case <-ctx.Done(): // ΠΏΠΎΠ»ΡΡΠ΅Π½ ΡΠΈΠ³Π½Π°Π» Π·Π°ΠΊΡΡΡΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°
// ΠΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡ ΡΠ΅ΡΡΡΡΡ
s.stopCh <- struct{}{} // ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΎΠ± ΡΡΠΏΠ΅ΡΠ½ΠΎΠΌ Π·Π°ΠΊΡΡΡΠΈΠΈ
return
default:
// ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΎΡΠ΅ΡΠ΅Π΄Π½ΠΎΠΉ ΠΈΡΠ΅ΡΠ°ΡΠΈΠΈ
}
}
ΠΠ»Ρ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ HTTP ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π΄ΡΡΠ³ΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄:
// ΡΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Ρ ΠΎΡΠΌΠ΅Π½ΠΎΠΉ ΠΈ ΠΎΡΡΡΠΎΡΠΊΠΎΠΉ ShutdownTimeout
cancelCtx, cancel := context.WithTimeout(s.ctx, time.Duration(s.cfg.ShutdownTimeout*int(time.Second)))
defer cancel()
// ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ Π·Π°ΠΊΡΡΡΠΈΡ Π°ΠΊΡΠΈΠ²Π½ΡΡ
ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠΈ ShutdownTimeout
if err := s.httpServer.Shutdown(cancelCtx); err != nil {
return err
}
s.httpService.Shutdown() // ΠΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΠ΅ ΡΠ΅ΡΠ²ΠΈΡΡ
// ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΎΠ± ΡΡΠΏΠ΅ΡΠ½ΠΎΠΌ Π·Π°ΠΊΡΡΡΠΈΠΈ HTTP ΡΠ΅ΡΠ²Π΅ΡΠ°
s.stopCh <- struct{}{}
ΠΠ΄ΠΈΠ½ ΠΈΠ· Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡΠ΄Π°ΡΠ½ΡΡ
ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ github.com/pkg/errors.
ΠΠ΅ΡΠ²ΠΎΠ½Π°ΡΠ°Π»ΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π» Π΅Π³ΠΎ, Π½ΠΎ ΡΠΎ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΡΡΠ°Π»ΠΎ Π½Π΅ Ρ
Π²Π°ΡΠ°ΡΡ ΡΡΡΡΠΊΡΡΡΠ½ΠΎΡΡΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΠ΅ΡΠ΅ΡΠ΅Π» Π½Π° ΠΏΡΠΎΡΡΠΎΠΉ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΉ ΠΏΠ°ΠΊΠ΅Ρ.
Π‘ΡΡΡΠΊΡΡΡΠ° Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΎΡΠΈΠ±ΠΊΠΈ:
type Error struct {
ID uint64 // ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΉ Π½ΠΎΠΌΠ΅Ρ ΠΎΡΠΈΠ±ΠΊΠΈ
Code string // ΠΊΠΎΠ΄ ΠΎΡΠΈΠ±ΠΊΠΈ
Msg string // ΡΠ΅ΠΊΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ
Caller string // ΡΠ°ΠΉΠ», ΡΡΡΠΎΠΊΠ° ΠΈ Π½Π°ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Π° Π² ΠΌΠ΅ΡΡΠ΅ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ
Args string // ΡΡΡΠΎΠΊΠ° Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ²
CauseErr error // ΠΎΡΠΈΠ±ΠΊΠ° - ΠΏΡΠΈΡΠΈΠ½Π°
CauseMsg string // ΡΠ΅ΠΊΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ - ΠΏΡΠΈΡΠΈΠ½Ρ
Trace string // ΡΡΠ΅ΠΊ Π²ΡΠ·ΠΎΠ²Π° Π² ΠΌΠ΅ΡΡΠ΅ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ
}
ΠΠ½Π΅ ΡΠ΄ΠΎΠ±Π½ΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΡΠΈΠΏΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΌΠΈ ΠΎΡΠΈΠ±ΠΊΠ°ΠΌΠΈ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΊΠΎΠ΄ ΠΎΡΠΈΠ±ΠΊΠΈ Π²ΡΠ΄Π΅Π»Π΅Π½ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌ Π°ΡΡΠΈΠ±ΡΡΠΎΠΌ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Π°Π΄Π°ΠΏΡΠ΅ΡΠ΅ 1Π‘ ΠΊ IBM MQ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ ΠΏΡΠΎΡΡΠΎΠΉ 4 ΡΠΈΠΌΠ²ΠΎΠ»ΡΠ½ΡΠΉ ΡΠΈΡΠ»ΠΎΠ²ΠΎΠΉ ΠΊΠΎΠ΄. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΎΡΠΈΠ±ΠΊΠΈ Π½Π°ΡΠΈΠ½Π°ΡΡΠΈΠ΅ΡΡ Ρ "8Ρ Ρ Ρ " ΠΎΡΠ½ΠΎΡΠΈΠ»ΠΈΡΡ ΠΊ HTTP, Ρ "7Ρ Ρ Ρ " - ΠΊ IBM MQ.
Caller - ΡΠ°ΠΉΠ», ΡΡΡΠΎΠΊΠ° ΠΈ Π½Π°ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Π° Π² ΠΌΠ΅ΡΡΠ΅ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ. Π£Π΄ΠΎΠ±Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ, Π΅ΡΠ»ΠΈ Π½Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡ ΠΏΠΎΠ»Π½ΡΠΉ ΡΡΠ΅ΠΊ. ΠΡΠΈΠΌΠ΅Ρ Π²ΡΠ²ΠΎΠ΄Π°:
httpserver.go:[209] - (*Server).Run()
Caller Π²ΡΡΠΈΡΠ»ΡΠ΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ
func caller(depth int) string {
pc := make([]uintptr, 15)
n := runtime.Callers(depth+1, pc)
frame, _ := runtime.CallersFrames(pc[:n]).Next()
idxFile := strings.LastIndexByte(frame.File, '/')
idx := strings.LastIndexByte(frame.Function, '/')
idxName := strings.IndexByte(frame.Function[idx+1:], '.') + idx + 1
return frame.File[idxFile+1:] + ":[" + strconv.Itoa(frame.Line) + "] - " + frame.Function[idxName+1:] + "()"
}
Args - ΠΎΡΠ΄Π΅Π»ΡΠ½Π°Ρ ΡΡΡΠΎΠΊΠ° Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΏΡΠΈ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΡΠ΅Π»Π΅ΠΉ ΠΎΡΠ»Π°Π΄ΠΊΠΈ.
CauseErr ΠΈ CauseMsg - ΠΈΡΡ ΠΎΠ΄Π½Π°Ρ ΠΎΡΠΈΠ±ΠΊΠ° ΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ, Π΅ΡΠ»ΠΈ ΠΎΠ±ΠΎΡΠ°ΡΠΈΠ²Π°Π΅ΠΌ ΡΡΠΆΡΡ ΠΎΡΠΈΠ±ΠΊΡ Π² ΡΠ²ΠΎΡ ΡΡΡΡΠΊΡΡΡΡ.
Trace - ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ ΡΡΠ΅ΠΉΡ ΡΡΠ΅ΠΊΠ°. ΠΠ»Ρ Π΅Π³ΠΎ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π» Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ²ΠΎΠ΅ΠΎΠ±ΡΠ°Π·Π½ΡΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄. ΠΡΠΈ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Π» Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΏΡΡΡΡΡ ΠΎΡΠΈΠ±ΠΊΡ ΠΈΠ· ΠΏΠ°ΠΊΠ΅ΡΠ° github.com/pkg/errors ΠΈ ΠΏΠ΅ΡΠ°ΡΠ°Π» Π΅Π΅ Ρ ΠΊΠ»ΡΡΠΎΠΌ '%+v'. Π ΡΡΠΎΠΌ ΡΠ΅ΠΆΠΈΠΌΠ΅ ΠΎΠ½Π° Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΡΠ΅ΠΊ.
fmt.Sprintf("'%+v'", pkgerr.New(""))
ΠΠ»Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ Error, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π²ΡΠ²ΠΎΠ΄ Π² ΡΠΎΠΊΡΠ°ΡΠ΅Π½Π½ΠΎΠΌ ΡΠΎΡΠΌΠ°ΡΠ΅.
func (e *Error) Error() string {
mes := fmt.Sprintf("ID=[%v], code=[%s], mes=[%s]", e.ID, e.Code, e.Msg)
if e.Args != "" {
mes = fmt.Sprintf("%s, args=[%s]", mes, e.Args)
}
if e.CauseMsg != "" {
mes = fmt.Sprintf("%s, causemes=[%s]", mes, e.CauseMsg)
}
return mes
}
ΠΡΠΈΠΌΠ΅Ρ Π²ΡΠ²ΠΎΠ΄Π° Π² ΡΠΎΠΊΡΠ°ΡΠ΅Π½Π½ΠΎΠΌ ΡΠΎΡΠΌΠ°ΡΠ΅
ID=[1], code=[8004], mes=[Error message], args=['arg1', 'arg2', 'arg3']
ΠΠ»Ρ ΡΠ°ΡΡΠΈΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π²ΡΠ²ΠΎΠ΄Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ ΠΊΠ»ΡΡΠΈ
// %s print the error code, message, arguments, and cause message.
// %v in addition to %s, print caller
// %+v extended format. Each Frame of the error's StackTrace will be printed in detail.
func (e *Error) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
fmt.Fprint(s, e.Error())
fmt.Fprintf(s, ", caller=[%s]", e.Caller)
if s.Flag('+') {
fmt.Fprintf(s, ", trace=%s", e.Trace)
return
}
case 's':
fmt.Fprint(s, e.Error())
case 'q':
fmt.Fprint(s, e.Error())
}
}
ΠΡΠΈΠΌΠ΅Ρ Π²ΡΠ²ΠΎΠ΄Π° Ρ ΠΊΠ»ΡΡΠΎΠΌ '%+v'
ID=[1], code=[8004], mes=[Error message], args=['arg1', 'arg2', 'arg3'], caller=[handler_echo.go:[31] - (*Service).EchoHandler.func1()], trace='
github.com/romapres2010/httpserver/error.New
D:/golang/src/github.com/romapres2010/httpserver/error/error.go:72
github.com/romapres2010/httpserver/httpserver/httpservice.(*Service).EchoHandler.func1
D:/golang/src/github.com/romapres2010/httpserver/httpserver/httpservice/handler_echo.go:31
...
ΠΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½Π½ΡΠΉ ΡΠΎΡΠΌΠ°Ρ Π²ΡΠ²ΠΎΠ΄Π° Π½Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Ρ ΡΡΡΡΠΊΡΡΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ. ΠΡΠΎ ΡΠ΄Π΅Π»Π°Π½ΠΎ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎ Π΄Π»Ρ Π±ΠΎΠ»Π΅Π΅ ΡΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ ΡΡΠ΅Π½ΠΈΡ Π»ΠΎΠ³Π° Π² Ρ ΠΎΠ΄Π΅ ΠΎΡΠ»Π°Π΄ΠΊΠΈ. ΠΡΠ»ΠΈ Π½ΡΠΆΠ΅Π½ Π±ΠΎΠ»Π΅ ΡΡΡΠΎΠ³ΠΈΠΉ ΡΠΎΡΠΌΠ°Ρ - Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΠΎΠΏΡΠ°Π²ΠΈΡΡ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ Format.
ΠΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π΄Π²Π° ΠΌΠ΅ΡΠΎΠ΄Π° Π΄Π»Ρ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ:
- Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠΉ ΠΎΡΠΈΠ±ΠΊΠΈ
New(code string, msg string, args ...interface{}) error
- ΠΠ±ΠΎΡΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅ΠΉ ΠΎΡΠΈΠ±ΠΊΠΈ
WithCause(code string, msg string, causeErr error, args ...interface{}) error
ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π»ΠΈΠ±ΠΎ Π²ΡΡΡΠΎΠΈΡΡ Π² ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ, Π»ΠΈΠ±ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ Π² args ...interface{}.
ΠΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΎΡ ΡΡΠΎΡΠΎΠ½Π½ΠΈΡ ΠΈ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² ΠΎΠ±ΠΎΡΠ°ΡΠΈΠ²Π°ΡΡΡΡ Π² ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΡ ΠΎΡΠΈΠ±ΠΊΡ Π² ΠΌΠ΅ΡΡΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ. ΠΡΡ ΠΎΠ΄Π½Π°Ρ ΠΎΡΠΈΠ±ΠΊΠ° Π²ΠΊΠ»Π°Π΄ΡΠ²Π°Π΅ΡΡΡ Π²Π½ΡΡΡΡ ΠΊΠ°ΡΡΠΎΠΌΠ½ΠΎΠΉ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ:
myerr = myerror.WithCause("8001", "Failed to read HTTP body: reqID", err, reqID)
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄:
- Π² ΡΠΎΡΠΊΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ, ΠΎΡΠΈΠ±ΠΊΠ° Π»ΠΎΠ³ΠΈΡΡΠ΅ΡΡΡ Π½Π° ΡΡΠΎΠ²Π½Π΅ INFO Π±Π΅Π· trace. Π ΡΡΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ, ΠΎΠ±ΡΡΠ½ΠΎ, Π½Π΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ, ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈ ΡΡΠΎ ΠΎΡΠΈΠ±ΠΊΠΎΠΉ, ΠΈΠ»ΠΈ ΠΎΠ½Π° Π±ΡΠ΄Π΅Ρ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½Π° Π½Π° ΡΡΠΎΠ²Π½Π΅ Π²ΡΡΠ΅
- ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ΅ ΠΎΡΠΈΠ±ΠΎΠΊ Π½Π° ΡΡΠΎΠ²Π΅Π½Ρ Π²Π²Π΅ΡΡ ΠΎΠ½Π° ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ Π½Π΅ ΠΎΠ±ΠΎΡΠ°ΡΠΈΠ²Π°Π΅ΡΡΡ Π² WithCause() ΠΈ Π½Π΅ Π»ΠΎΠ³ΠΈΡΡΠ΅ΡΡΡ
- Π² ΡΠΎΡΠΊΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ Π»ΠΎΠ³ΠΈΡΡΠ΅ΡΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π½Π° ΡΡΠΎΠ²Π½Π΅ INFO. ΠΡΠΈΠ±ΠΊΠ° ΠΏΠ΅ΡΠ΅ΡΡΠ°Π΅Ρ Π±ΡΡΡ ΠΎΡΠΈΠ±ΠΊΠΎΠΉ.
- Π΅ΡΠ»ΠΈ ΠΎΡΠΈΠ±ΠΊΠ° Π΄ΠΎΡΠ»Π° Π½Π΅ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½Π½ΠΎΠΉ Π΄ΠΎ ΡΠ°ΠΌΠΎΠ³ΠΎ Π²Π΅ΡΡ Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ, Π·Π½Π°ΡΠΈΡ ΡΡΠΎ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΡΠΈΠ±ΠΊΠ° ΠΈ ΠΎΠ½Π° Π»ΠΎΠ³ΠΈΡΡΠ΅ΡΡΡ Π½Π° ΡΡΠΎΠ²Π½Π΅ ERROR Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΉ Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎΡΡΡΡ, Π²ΠΊΠ»ΡΡΠ°Ρ trace.
ΠΡΠΈΠΌΠ΅Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΈ ΠΎΡΠΈΠ±ΠΊΠ΅ ΡΡΠ΅Π½ΠΈΡ ΡΠ΅Π»Π° HTTP Π·Π°ΠΏΡΠΎΡΠ°:
requestBuf, err := ioutil.ReadAll(r.Body)
if err != nil {
myerr = myerror.WithCause("8001", "Failed to read HTTP body: reqID", err, reqID)
mylog.PrintfErrorInfo(myerr) // ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠ΅ ΡΠΎΠΊΡΠ°ΡΠ΅Π½Π½ΠΎΠ΅ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ
s.processError(myerr, w, http.StatusInternalServerError, reqID) // ΡΠ°ΡΡΠΈΡΠ΅Π½Π½ΠΎΠ΅ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ Π² HTTP response
return myerr
}
ΠΠ΅ΡΠΎΠ΄ΠΎΠΌ processError Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΡΠΈΠ±ΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°ΡΡΡΡ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ HTTP ΠΎΡΠ²Π΅ΡΠ° ΠΈ/ΠΈΠ»ΠΈ ΡΠ΅Π»ΠΎ ΠΎΡΠ²Π΅ΡΠ°. ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ ΡΠ°ΠΊΠΎΠ³ΠΎ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΡΡΡ Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ ΡΠ΅ΡΠ²Π΅ΡΠ° - ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ HTTPErrLog, ΠΈΠ»ΠΈ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ POST Π½Π° /httperrlog.
POST /httperrlog HTTP/1.1
HTTP-Err-Log: HEADER | BODY
ΠΡΠΈ Π·Π°ΠΏΠΈΡΠΈ ΠΌΠ½ΠΎΠ³ΠΎΡΡΡΠΎΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΠ° Π² HTTP header Π½ΡΠΆΠ½ΠΎ Π½Π΅ Π·Π°Π±ΡΠ²Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡ Π²ΡΠ΅ ΡΠΏΡΠ°Π²Π»ΡΡΡΠΈΠ΅ ΡΠΈΠΌΠ²ΠΎΠ»Ρ
// carriage return (CR, ASCII 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII 0x0)
headerReplacer := strings.NewReplacer("\x0a", " ", "\x0d", " ", "\x00", " ")
w.Header().Set("Err-Trace", headerReplacer.Replace(myerr.Trace))
ΠΠ»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΡΠΎΠ²Π½ΡΠΌΠΈ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ ΠΏΠ°ΠΊΠ΅Ρ github.com/hashicorp/logutils.
ΠΠ· ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΡΠΏΠΈΡΠΊΠ° ΡΡΠΎΠ²Π½Π΅ΠΉ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ RFC 5424 β The Syslog Protocol, Π² ΡΠ°Π±Π»ΠΎΠ½Π΅ ΠΎΡΡΠ°Π²ΠΈΠ» ΡΠΎΠ»ΡΠΊΠΎ:
- debug β ΠΏΠΎΠ΄ΡΠΎΠ±Π½Π°Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ
- info β ΠΏΠΎΠ»Π΅Π·Π½ΡΠ΅ ΡΠΎΠ±ΡΡΠΈΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π·Π°ΠΏΡΡΠΊ/ΠΎΡΡΠ°Π½ΠΎΠ² ΡΠ΅ΡΠ²ΠΈΡΠ°
- error β ΠΎΡΠΈΠ±ΠΊΠΈ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ, ΡΡΠ΅Π±ΡΡΡΠΈΠ΅ Π²ΠΌΠ΅ΡΠ°ΡΠ΅Π»ΡΡΡΠ²Π°
ΠΠ°ΡΡΠΎΠΌΠ½ΡΠΉ ΠΏΠ°ΠΊΠ΅Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡΡΠΈΠ»ΡΡ ΠΊΡΠ°ΠΉΠ½Π΅ ΠΏΡΠΎΡΡΡΠΌ - Π²ΡΠ΅Π³ΠΎ 100 ΡΡΡΠΎΠΊ
Π‘ΡΡΠ»ΠΊΠ° Π½Π° ΠΏΠΎΠ»Π΅Π·Π½ΡΡ ΡΡΠ°ΡΡΡ ΠΎΡ Dave Cheney Letβs talk about logging.
ΠΡΠ»ΠΈ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½Π½ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ ΡΠ»ΠΈΡΠΊΠΎΠΌ ΠΏΡΠΎΡΡΡΠΌ - ΡΠΎ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΡ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ Π² ΡΡΠΎΡΠΎΠ½Ρ A simple logging interface for Go.
ΠΡΠ΅ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΠ΄Π΅Ρ ΡΠ΅ΡΠ΅Π· ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ ΠΏΠ°ΠΊΠ΅Ρ "log". ΠΠΎ Π΄Π»Ρ Π½Π΅Π³ΠΎ ΠΏΠΎΠ΄ΠΌΠ΅Π½ΡΠ΅ΡΡΡ Π²ΡΠ²ΠΎΠ΄ Π½Π° ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΉ Π»ΠΎΠ³Π΅Ρ github.com/hashicorp/logutils.
// logFilter represent a custom logger seting
var logFilter = &logutils.LevelFilter{
Levels: []logutils.LogLevel{"DEBUG", "INFO", "ERROR"},
MinLevel: logutils.LogLevel("INFO"), // initial setting
Writer: os.Stderr, // initial setting
}
// InitLogger init custom logger
func InitLogger(wrt io.Writer) {
logFilter.Writer = wrt // custom logger
log.SetOutput(logFilter) // set std logger to our custom
}
ΠΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°ΡΡ Π² ΡΠ°ΠΉΠ», Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ Π½Π° ΡΡΠΎΠ²Π½Π΅ main ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π»ΠΎΠ³ ΡΠ°ΠΉΠ» ΠΈ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ MultiWriter
// Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎΠ΅ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΡΠ°ΠΉΠ»
if logFileFlag != "" {
// Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π² ΠΈΠΌΡ Π»ΠΎΠ³ ΡΠ°ΠΉΠ»Π° Π΄Π°ΡΡ ΠΈ Π²ΡΠ΅ΠΌΡ
logFileFlag = strings.Replace(logFileFlag, "%s", time.Now().Format("2006_01_02_150405"), 1)
// ΠΎΡΠΊΡΡΠ²Π°Π΅ΠΌ Π»ΠΎΠ³ ΡΠ°ΠΉΠ» Π½Π° Π·Π°ΠΏΠΈΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ APPEND
logFile, err := os.OpenFile(logFileFlag, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
myerr := myerror.WithCause("6020", "Error open log file: Filename", err, logFileFlag)
mylog.PrintfErrorMsg(fmt.Sprintf("%+v", myerr))
return myerr
}
if logFile != nil {
defer logFile.Close()
}
wrt := io.MultiWriter(os.Stderr, logFile) // ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎ ΠΏΠΈΡΠ΅ΠΌ Π² os.Stderr ΠΈ ΡΠ°ΠΉΠ»
mylog.InitLogger(wrt) // ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ Π»ΠΎΠ³Π΅Ρ Π½Π° ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΉ
} else {
mylog.InitLogger(os.Stderr)
}
ΠΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ INFO ΠΈ DEBUG ΡΠ΄Π΅Π»Π°Π½ΠΎ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π±ΠΎΠ»Π΅Π΅ Π΄ΡΡΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΡΠΌ ΡΠ΅ΠΌ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΡΠΈΠ±ΠΎΠΊ. ΠΡΠΈΠΌΠ΅Ρ Π½ΠΈΠΆΠ΅
2020/03/10 17:56:39 [INFO] - httpserver.go:[61] - New() - Creating new HTTP server
2020/03/10 17:56:39 [INFO] - httpserver.go:[141] - New() - Created new TCP listener: network = 'tcp', address ['127.0.0.1:3000']
2020/03/10 17:56:39 [INFO] - httpserver.go:[155] - New() - Handler is registered: Path, Method ['/echo', 'POST']
2020/03/10 17:56:39 [INFO] - httpserver.go:[155] - New() - Handler is registered: Path, Method ['/signin', 'POST']
2020/03/10 17:56:39 [INFO] - httpserver.go:[155] - New() - Handler is registered: Path, Method ['/refresh', 'POST']
2020/03/10 17:56:39 [INFO] - httpserver.go:[179] - New() - HTTP server is created
2020/03/10 17:56:39 [INFO] - daemon.go:[121] - New() - New daemon is created
2020/03/10 17:56:39 [INFO] - daemon.go:[128] - (*Daemon).Run() - Starting daemon
2020/03/10 17:56:39 [INFO] - daemon.go:[133] - (*Daemon).Run() - Daemon is running. For exit <CTRL-c>
2020/03/10 17:56:39 [INFO] - httpserver.go:[209] - (*Server).Run() - Starting HTTP server
2020/03/10 17:57:22 [INFO] - daemon.go:[142] - (*Daemon).Run() - Exiting, got signal ['interrupt']
2020/03/10 17:57:22 [INFO] - daemon.go:[155] - (*Daemon).Shutdown() - Shutting down daemon
2020/03/10 17:57:22 [INFO] - httpserver.go:[215] - (*Server).Shutdown() - Waiting for shutdown HTTP Server: sec ['30']
2020/03/10 17:57:22 [INFO] - httpserver.go:[231] - (*Server).Shutdown() - HTTP Server shutdown successfuly
2020/03/10 17:57:22 [INFO] - daemon.go:[167] - (*Daemon).Shutdown() - Daemon is shutdown
2020/03/10 17:57:22 [INFO] - main.go:[163] - main.func1() - Server is shutdown
Π ΡΠ΅ΠΆΠΈΠΌΠ΅ ERROR ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΡΠΌΠ°Ρ Π²ΡΠ²ΠΎΠ΄Π° ΠΈΠ· ΡΠ°Π·Π΄Π΅Π»Π° Π²ΡΡΠ΅ ΠΏΡΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΎΡΠΈΠ±ΠΎΠΊ.
ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΡΠΎΠ²Π½Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠ΄Π΅Π»Π°Π½Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ:
func PrintfInfoMsg(mes string, args ...interface{}) {
printfMsg("[INFO]", 0, mes, args...)
}
func PrintfDebugMsg(mes string, args ...interface{}) {
printfMsg("[DEBUG]", 0, mes, args...)
}
func PrintfErrorMsg(mes string, args ...interface{}) {
printfMsg("[ERROR]", 0, mes, args...)
}
ΠΠ»Ρ ΠΌΠ΅Π½Ρ ΡΡΠΎ ΡΠ΄ΠΎΠ±Π½Π΅Π΅, ΡΠ΅ΠΌ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΠΎΡΠΊΠ΅ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠΉ ΡΡΠΎΠ²Π΅Π½Ρ. ΠΡΠ΅ ΠΎΠ΄ΠΈΠ½ ΠΏΠ»ΡΡ - Π»Π΅Π³ΠΊΠΎ ΡΠ΅Π½ΡΡΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ ΠΎΡΠΊΠ»ΡΡΠΈΡΡ Π²ΡΠ²ΠΎΠ΄ DEBUG ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄Π΅ Π² ΠΏΡΠΎΠ΄ΡΠΊΡΠΈΠ².
Π§ΡΠΎΠ±Ρ ΡΠ½ΠΈΠ·ΠΈΡΡ Π·Π°ΡΡΠ°ΡΡ Π½Π° Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ INFO ΠΈ DEBUG, Π»ΡΡΡΠ΅ ΠΎΡΠΊΠ°Π·Π°ΡΡΡΡ ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΡΡΠΎΠΊ Π² ΡΠΎΡΠΊΠ΅ Π²ΡΠ·ΠΎΠ²Π°. ΠΠΌΠ΅ΡΡΠΎ
mylog.PrintfInfoMsg(fmt.Sprintf("Create new TCP listener network='tcp', address='%s'", serverCfg.ListenSpec))
Π»ΡΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
mylog.PrintfInfoMsg("Created new TCP listener: network = 'tcp', address", cfg.ListenSpec)
Π’Π΅ΡΡΡ ΠΏΠΎΠΊΠ°Π·Π°Π»ΠΈ, ΡΡΠΎ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΡΠ°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄Π°, Π½Π°ΠΊΠ»Π°Π΄Π½ΡΠ΅ ΡΠ°ΡΡ
ΠΎΠ΄Ρ Π½Π° Π²ΡΠ·ΠΎΠ²Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ DEBUG Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ INFO Π½Π΅ ΠΏΡΠ΅Π²ΡΡΠΈΠ»ΠΈ 1%.
Π ΡΡΠΎΠΌ Π΅ΡΡΡ ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΠΉ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ - ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ ΡΡΠΎΠ²Π΅Π½Ρ Ρ INFO Π½Π° DEBUG Π±Π΅Π· ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ° Π²ΡΠ·ΠΎΠ²ΠΎΠΌ POST Π½Π° /loglevel.
POST /loglevel HTTP/1.1
Log-Level-Filter: DEBUG | ERROR | INFO
ΠΠ»Ρ Π°Π½Π°Π»ΠΈΠ·Π° ΡΠ»ΠΎΠΆΠ½ΡΡ
ΡΠΈΡΡΠ°ΡΠΈΠΉ, ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΈΠΌΠ΅ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ HTTP ΡΡΠ°ΡΠΈΠΊΠ° ΠΏΡΠΎΡ
ΠΎΠ΄ΡΡΠ΅Π³ΠΎ ΡΠ΅ΡΠ΅Π· ΡΠ΅ΡΠ²Π΅Ρ.
Π ΠΏΠ°ΠΊΠ΅ΡΠ΅ httplog ΡΠΎΠ±ΡΠ°Π½Ρ ΠΌΠ΅ΡΠΎΠ΄Ρ Π΄Π»Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ HTTP header ΠΈ body:
- Π²Ρ ΠΎΠ΄ΡΡΠ΅Π³ΠΎ Π·Π°ΠΏΡΠΎΡΠ°
- ΠΈΡΡ ΠΎΠ΄ΡΡΠ΅Π³ΠΎ ΠΎΡΠ²Π΅ΡΠ°
- ΠΈΡΡ ΠΎΠ΄ΡΡΠ΅Π³ΠΎ Π·Π°ΠΏΡΠΎΡΠ°
- Π²Ρ ΠΎΠ΄ΡΡΠ΅Π³ΠΎ ΠΎΡΠ²Π΅ΡΠ°
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° ΡΠΈΠΏΠ° Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ Π»ΠΎΠ³ ΡΠ°ΠΉΠ»Π° ΠΌΠΎΠΆΠ΅Ρ Π·Π°Π΄Π°Π²Π°ΡΡΡΡ Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ - ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ HttpLog ΠΈ HTTPLogType, ΠΈΠ»ΠΈ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ POST Π½Π° /httplog.
POST /httplog HTTP/1.1
Http-Log: TRUE
Http-Log-Type: INREQ | OUTREQ | INRESP | OUTRESP | BODY
Π ΡΠ°Π±Π»ΠΎΠ½ Π²ΠΊΠ»ΡΡΠ΅Π½Ρ Π΄Π²Π° Π±Π°Π·ΠΎΠ²ΡΡ
ΡΠΏΠΎΡΠΎΠ±Π° Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ: HTTP Basic Authentication ΠΈΠ»ΠΈ MS AD Authentication.
ΠΠ»Ρ MS AD Authentication ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° gopkg.in/korylprince/go-ad-auth.v2.
ΠΠ° ΡΡΠΎΠ²Π½Π΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°, ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°ΡΡ ΡΠΈΠΏ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΊ ΡΠ΅ΡΠ²Π΅ΡΡ MS AD.
[AUTHENTIFICATION]
AuthType = INTERNAL | MSAD | NONE
MSADServer = company.com
MSADPort = 389
MSADBaseDN = OU=company, DC=dc, DC=corp
MSADSecurity = SecurityNone
ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΈ ΠΏΠ°ΡΠΎΠ»Ρ Π΄Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ HTTP Basic Authentication ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠΌΠ°Π½Π΄ΡΡ ΡΡΡΠΎΠΊΡ ΠΏΡΠΈ ΡΡΠ°ΡΡΠ΅ ΡΠ΅ΡΠ²Π΅ΡΠ°.
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ JSON Web Token (JWT) Π·Π°Π΄Π°Π΅ΡΡΡ Π½Π° ΡΡΠΎΠ²Π½Π΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΡΠ΅ΡΠ²Π΅ΡΠ°. ΠΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ ΡΠΎΠΊΠ΅Π½Π° Π·Π°Π΄Π°Π΅ΡΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠΌ JWTExpiresAt (JWTExpiresAt=0 - Π²ΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ Π½Π΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΎ). Π‘Π΅ΠΊΡΠ΅ΡΠ½ΡΠΉ ΠΊΠ»ΡΡ Π΄Π»Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ JWT ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠΌΠ°Π½Π΄ΡΡ ΡΡΡΠΎΠΊΡ ΠΏΡΠΈ ΡΡΠ°ΡΡΠ΅ ΡΠ΅ΡΠ²Π΅ΡΠ°.
[JWT]
UseJWT = true
JWTExpiresAt = 20000
ΠΠ»Ρ ΡΠ°Π±ΠΎΡΡ Ρ JWT ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° github.com/dgrijalva/jwt-go.
ΠΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° JWT: ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅, ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°, ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ cookie ΡΠΎΠ±ΡΠ°Π½ΠΎ Π² Π½Π΅Π±ΠΎΠ»ΡΡΠΎΠΉ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΉ ΠΏΠ°ΠΊΠ΅Ρ jwt
ΠΠΎΠ³ΠΈΠΊΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ JWT ΡΠ»Π΅Π΄ΡΡΡΠ°Ρ:
- Π΅ΡΠ»ΠΈ JWT Π²ΡΠΊΠ»ΡΡΠ΅Π½, ΡΠΎ ΠΏΡΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π²Ρ ΠΎΠ΄ΡΡΠ΅ΠΌ Π·Π°ΠΏΡΠΎΡΠ΅ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ HTTP Basic Authentication ΠΈΠ»ΠΈ MS AD Authentication
- Π΅ΡΠ»ΠΈ JWT Π²ΠΊΠ»ΡΡΠ΅Π½, ΡΠΎ Π²ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ Π±Π»ΠΎΠΊΠΈΡΡΡΡΡΡ (StatusUnauthorized), ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½Π° Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΈ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ JWT
- Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ JWT Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ POST Π½Π° /signin
- ΠΏΡΠΈ ΡΡΠΏΠ΅ΡΠ½ΠΎΠΉ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΡΠΎΡΠΌΠΈΡΡΠ΅ΡΡΡ JSON Web Token Claim (Π² Claim Π²ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ ΠΈΠΌΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ), ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ Π²ΡΠ΅ΠΌΡ Π΅Π³ΠΎ ΠΆΠΈΠ·Π½ΠΈ
- ΠΈΠ· Claims ΡΠΎΡΠΌΠΈΡΡΠ΅ΡΡΡ JSON Web Token, ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠΌ HS256 Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΡΠ΅ΠΊΡΠ΅ΡΠ½ΡΠΌ ΠΊΠ»ΡΡΠΎΠΌ
- ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Token ΠΏΠΎΠΌΠ΅ΡΠ°Π΅ΡΡΡ Π² http Cookie "token". ΠΠ»Ρ Cookie ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½ΠΎΠ΅ Token Π²ΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ
- ΠΏΡΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠΈΡ Π·Π°ΠΏΡΠΎΡΠ°Ρ , ΠΈΠ· http Cookie ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΡΡΡ JWT ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΡΡΡ. ΠΡΠ»ΠΈ Π²ΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ Π·Π°ΠΊΠΎΠ½ΡΠΈΠ»ΠΎΡΡ, ΡΠΎ StatusUnauthorized
- ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ JWT Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ POST Π½Π° /refresh
- logout Π½Π΅ ΠΏΡΠ΅Π΄ΡΡΠΌΠΎΡΡΠ΅Π½
ΠΠ»Ρ ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ ΠΏΠ΅ΡΠ΅ΡΠ΅Π» Ρ golang/dep/cmd/dep Π½Π° go mod, Π½ΠΎ Π΄Π»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ ΠΏΠΎ ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΠ°ΠΏΠΊΠ° vendor Π² ΠΊΠΎΡΠ½Π΅ ΠΏΡΠΎΠ΅ΠΊΡΠ°. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Ρ ΡΠ°Π½ΠΈΡΡ "ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠ΅" Π²Π΅ΡΡΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Π² ΡΠ²ΠΎΠ΅ΠΌ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ°. ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ.
go get -u ./../...
go mod vendor
ΠΡΠΈ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄Π΅ Π½Π° go mod ΡΡΠΎΠ»ΠΊΠ½ΡΠ»ΡΡ Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, ΡΡΠΎ ΡΠ°ΡΡΡ ΡΡΠΎΡΠΎΠ½Π½ΠΈΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΡΠ°Π±ΠΎΡΡ Ρ ΠΌΠΎΠ΄ΡΠ»ΡΠΌΠΈ ΠΈ Π·Π°Π³ΡΡΠΆΠ°Π΅ΡΡΡ Π½Π΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½Π°Ρ Π²Π΅ΡΡΠΈΡ. ΠΠ»Ρ ΡΠ°ΠΊΠΈΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Π½ΡΠΆΠ½ΠΎ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ Π² ΠΊΠΎΠ½ΡΠ΅ Π½ΠΎΠΌΠ΅Ρ Π½ΡΠΆΠ½ΠΎΠ³ΠΎ commit, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ:
go get github.com/ibm-messaging/mq-golang/ibmmq@19b946c
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡ Π±ΡΠ°Π» Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΠΈΠ· ΠΊΠ°ΡΠ°Π»ΠΎΠ³Π° vendor, Π½ΡΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΠΎΠΏΡΠΈΡ
go build -v -mod vendor
ΠΠ»Ρ ΡΠ±ΠΎΡΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΡΠΎΡΡΠΎΠΉ make ΡΠ°ΠΉΠ» Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ ΡΠ΅ΠΆΠΈΠΌΠ°ΠΌΠΈ (Π²Π·ΡΡ Π³Π΄Π΅-ΡΠΎ Π½Π° ΠΏΠΎΡΡΠΎΡΠ°Ρ ΠΈΠ½ΡΠ΅ΡΠ½Π΅ΡΠ°):
- rebuild - ΠΏΠΎΠ»Π½Π°Ρ ΠΏΠ΅ΡΠ΅ΡΠ±ΠΎΡΠΊΠ°
- build - ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠ°Π»ΡΠ½Π°Ρ ΡΠ±ΠΎΡΠΊΠ°
- check - ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΊΠΎΠ΄Π° Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ github.com/golangci/golangci-lint
ΠΡΠΈ ΡΠ±ΠΎΡΠ΅ Π² ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» Π²Π½Π΅Π΄ΡΡΠ΅ΡΡΡ Π²Π΅ΡΡΠΈΡ, Π΄Π°ΡΠ° ΡΠ±ΠΎΡΠΊΠΈ ΠΈ commit. ΠΡΠ° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡΡ Π² Π»ΠΎΠ³ ΡΠ°ΠΉΠ» - Π²Π΅ΡΡΠΌΠ° ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π΄Π»Ρ ΡΠ°Π·Π±ΠΎΡΠ° ΠΎΡΠΈΠ±ΠΎΠΊ.
ΠΠ»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΠ°ΠΊΠΎΠ³ΠΎ Π²Π½Π΅Π΄ΡΠ΅Π½ΠΈΡ, Π² main Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅
var (
version = "0.0.2" // Π½ΠΎΠΌΠ΅Ρ Π²Π΅ΡΡΠΈΠΈ, Π·Π°Π΄Π°Π΅ΡΡΡ ΡΡΠΊΠ°ΠΌΠΈ
commit = "unset" // Π½ΠΎΠΌΠ΅Ρ commit
buildTime = "unset" // Π΄Π°ΡΠ° ΠΈ Π²ΡΠ΅ΠΌΡ ΡΠ±ΠΎΡΠΊΠΈ
)
ΠΡΠΈ ΡΠ±ΠΎΡΠ΅ Π² make ΡΠ°ΠΉΠ»Π΅, Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΠΌ git ΠΎ commit
COMMIT?=$(shell git rev-parse --short HEAD)
BUILD_TIME?=$(shell date -u '+%Y-%m-%d_%H:%M:%S')
ΠΡΠΈ ΡΠ±ΠΎΡΠΊΠ΅ ΠΏΡΠΈΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΡΡΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΊ ΡΠ°Π½Π΅Π΅ ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΠΌ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌ (ΠΎΠΏΡΠΈΡ -ldflags "-X"), Π·Π°ΠΎΠ΄Π½ΠΎ ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½ΠΊΡ, ΠΏΠΎΠ΄ ΠΊΠΎΡΠΎΡΡΡ ΡΠΎΠ±ΠΈΡΠ°Π΅ΠΌ ΠΈ ΠΌΠ΅ΡΡΠΎ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΊΠ°
GOOS=${GOOS} go build -v -a -mod vendor \
-ldflags "-X main.commit=${COMMIT} -X main.buildTime=${BUILD_TIME}" \
-o bin/${GOOS}/${APP}
Π main.main Π² ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Π·Π°ΠΏΠΈΡΡΠ²Π°Ρ ΠΈΡΠΎΠ³ΠΎΠ²ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ Π²Π΅ΡΡΠΈΠΈ, commit ΠΈ Π΄Π°ΡΠ΅ ΡΠ±ΠΎΡΠΊΠΈ
app.Version = fmt.Sprintf("%s, commit '%s', build time '%s'", version, commit, buildTime)