github.com/cloudwego/kitex@v0.9.0/pkg/logid/logid.go (about) 1 /* 2 * Copyright 2023 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package logid 18 19 import ( 20 "context" 21 "strconv" 22 "strings" 23 "sync/atomic" 24 "time" 25 26 "github.com/bytedance/gopkg/lang/fastrand" 27 ) 28 29 const ( 30 logIDVersion = "02" 31 logIDMaxLength = 21 32 maxRandNum = 1<<24 - 1<<20 33 ) 34 35 var ( 36 logIDGenerator func(ctx context.Context) string 37 logIDExtra atomic.Value 38 ) 39 40 func init() { 41 SetLogIDGenerator(DefaultLogIDGenerator) 42 SetLogIDExtra("") 43 } 44 45 // SetLogIDGenerator allows custom log id generator 46 func SetLogIDGenerator(g func(ctx context.Context) string) { 47 logIDGenerator = g 48 } 49 50 // SetLogIDExtra allows custom log id extra 51 // For example, local ip address can be used to improve the uniqueness 52 func SetLogIDExtra(extra string) { 53 logIDExtra.Store(extra) 54 } 55 56 // loadLogIDExtra returns the log ID extra as a string. 57 // 58 // It does not take any parameters. 59 // It returns a string. 60 func loadLogIDExtra() string { 61 return logIDExtra.Load().(string) 62 } 63 64 // DefaultLogIDGenerator generates a default log ID using a combination of random numbers and timestamps. 65 // `SetLogIDExtra` can be used to add extra information to each log ID. 66 // The format is `<version><timestamp><extra><random>`, where 67 // - `<version>` is the version string, "02" by default 68 // - `<timestamp>` is the timestamp in milliseconds, consuming 13 digits 69 // - `<extra>` is the extra information string, empty by default 70 // - `<random>` is the random number, consuming 6 hex digits 71 // It returns a string that represents the generated log ID. 72 func DefaultLogIDGenerator(ctx context.Context) string { 73 r := fastrand.Uint32n(maxRandNum) + 1<<20 74 sb := strings.Builder{} 75 extra := loadLogIDExtra() 76 sb.Grow(logIDMaxLength + len(extra)) 77 sb.WriteString(logIDVersion) 78 ts := time.Now().UnixNano() / int64(time.Millisecond) 79 sb.WriteString(strconv.FormatUint(uint64(ts), 10)) 80 sb.WriteString(extra) 81 sb.WriteString(strconv.FormatUint(uint64(r), 16)) 82 return sb.String() 83 }