github.com/GuanceCloud/cliutils@v1.1.21/point/rand.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  //nolint:gosec
     7  package point
     8  
     9  import (
    10  	"fmt"
    11  	mrand "math/rand"
    12  	"time"
    13  
    14  	"github.com/GuanceCloud/cliutils"
    15  )
    16  
    17  type RandOption func(*ptRander)
    18  
    19  type ptRander struct {
    20  	pb,
    21  	fixedKeys,
    22  	fixedTags,
    23  	kvSorted,
    24  	stringValues bool
    25  
    26  	ntext,
    27  	ntags,
    28  	nfields,
    29  	keyLen,
    30  	valLen int
    31  
    32  	cat Category
    33  
    34  	tagKeys    []string
    35  	fieldKeys  []string
    36  	tagVals    []string
    37  	sampleText []string
    38  
    39  	ts time.Time
    40  
    41  	measurePrefix string
    42  }
    43  
    44  var defTags, defFields, defKeyLen, defValLen = 4, 10, 10, 17
    45  
    46  func NewRander(opts ...RandOption) *ptRander {
    47  	r := &ptRander{
    48  		ntags:        defTags,
    49  		nfields:      defFields,
    50  		keyLen:       defKeyLen,
    51  		valLen:       defValLen,
    52  		ts:           time.Now(),
    53  		cat:          Logging,
    54  		stringValues: true,
    55  	}
    56  
    57  	for _, opt := range opts {
    58  		opt(r)
    59  	}
    60  
    61  	// add tag/field keys
    62  	if r.fixedKeys {
    63  		for i := 0; i < r.ntags; i++ {
    64  			r.tagKeys = append(r.tagKeys, randStr(r.keyLen))
    65  		}
    66  
    67  		for i := 0; i < r.nfields; i++ {
    68  			r.fieldKeys = append(r.fieldKeys, randStr(r.keyLen))
    69  		}
    70  	}
    71  
    72  	if r.fixedTags {
    73  		// add tag keys
    74  		if len(r.tagKeys) == 0 {
    75  			for i := 0; i < r.ntags; i++ {
    76  				r.tagKeys = append(r.tagKeys, randStr(r.keyLen))
    77  			}
    78  		}
    79  
    80  		// add tag values
    81  		for range r.tagKeys {
    82  			r.tagVals = append(r.tagVals, randStr(r.valLen))
    83  		}
    84  	}
    85  
    86  	if r.ntext > 0 {
    87  		if len(r.sampleText) == 0 {
    88  			// nolint: lll
    89  			r.sampleText = []string{
    90  				`2022-10-27T16:12:46.699+0800	DEBUG	io	io/io.go:265	on tick(10s) to flush /v1/write/logging(0 pts), last flush 10.000006916s ago...`,
    91  				`2022-10-27T16:12:46.306+0800	DEBUG	dataway	dataway/send.go:219	send request https://openway.guance.com/v1/datakit/pull?token=tkn_2af4b19d7f5a4xxxxxxxxxxxxxxxxxxx&filters=true, proxy: , dwcli: 0x1400049e000, timeout: 30s(30s)`,
    92  				`2022-10-27T16:12:46.306+0800	DEBUG	dataway	dataway/cli.go:27	performing request%!(EXTRA string=method, string=GET, string=url, *url.URL=https://openway.guance.com/v1/datakit/pull?token=tkn_2af4b19dxxxxxxxxxxxxxxxxxxxxxxxx&filters=true)`,
    93  				`2022-10-27T16:12:46.305+0800	DEBUG	ddtrace	trace/filters.go:235	keep tid: 2790747027482021869 service: compiled-in-example resource: ./demo according to PRIORITY_AUTO_KEEP and sampling ratio: 100%`,
    94  				`2022-10-27T16:12:46.305+0800	DEBUG	ddtrace	trace/filters.go:235	keep tid: 1965248471827589152 service: compiled-in-example resource: file-not-exists according to PRIORITY_AUTO_KEEP and sampling ratio: 100%`,
    95  				`2022-10-27T16:12:46.305+0800	DEBUG	ddtrace	trace/filters.go:102	keep tid: 2790747027482021869 service: compiled-in-example resource: ./demo according to PRIORITY_AUTO_KEEP.`,
    96  				`2022-10-27T16:12:46.305+0800	DEBUG	ddtrace	trace/filters.go:102	keep tid: 1965248471827589152 service: compiled-in-example resource: file-not-exists according to PRIORITY_AUTO_KEEP.`,
    97  				`2022-10-27T16:12:45.481+0800	DEBUG	disk	disk/utils.go:62	disk---fstype:nullfs ,device:/Applications/xxxxxx.app ,mountpoint:/private/var/folders/71/4pnfjgwn0x3fcy4r3ddxw1fm0000gn/T/AppTranslocation/1A552256-4134-4CAA-A4FF-7D2DEF11A6AC`,
    98  				`2022-10-27T16:12:45.481+0800	DEBUG	disk	disk/utils.go:62	disk---fstype:nullfs ,device:/Applications/oss-browser.app ,mountpoint:/private/var/folders/71/4pnfjgwn0x3fcy4r3ddxw1fm0000gn/T/AppTranslocation/97346A30-EA8C-4AC8-991D-3AD64E2479E1`,
    99  				`2022-10-27T16:12:45.481+0800	DEBUG	disk	disk/utils.go:62	disk---fstype:nullfs ,device:/Applications/Sublime Text.app ,mountpoint:/private/var/folders/71/4pnfjgwn0x3fcy4r3ddxw1fm0000gn/T/AppTranslocation/0EE2FB5D-6535-47AB-938B-DCB79CE11CE6`,
   100  			}
   101  		}
   102  	}
   103  
   104  	return r
   105  }
   106  
   107  func WithRandSampleText(st []string) RandOption     { return func(r *ptRander) { r.sampleText = st } }
   108  func WithRandStringValues(on bool) RandOption       { return func(r *ptRander) { r.stringValues = on } }
   109  func WithRandTime(t time.Time) RandOption           { return func(r *ptRander) { r.ts = t } }
   110  func WithRandText(n int) RandOption                 { return func(r *ptRander) { r.ntext = n } }
   111  func WithRandTags(n int) RandOption                 { return func(r *ptRander) { r.ntags = n } }
   112  func WithRandFields(n int) RandOption               { return func(r *ptRander) { r.nfields = n } }
   113  func WithRandKeyLen(n int) RandOption               { return func(r *ptRander) { r.keyLen = n } }
   114  func WithRandValLen(n int) RandOption               { return func(r *ptRander) { r.valLen = n } }
   115  func WithCategory(c Category) RandOption            { return func(r *ptRander) { r.cat = c } }
   116  func WithRandMeasurementPrefix(s string) RandOption { return func(r *ptRander) { r.measurePrefix = s } }
   117  func WithKVSorted(on bool) RandOption               { return func(r *ptRander) { r.kvSorted = on } }
   118  func WithFixedKeys(on bool) RandOption              { return func(r *ptRander) { r.fixedKeys = on } }
   119  func WithFixedTags(on bool) RandOption              { return func(r *ptRander) { r.fixedTags = on } }
   120  func WithRandPB(on bool) RandOption                 { return func(r *ptRander) { r.pb = on } }
   121  
   122  func (r *ptRander) Rand(count int) []*Point {
   123  	if count <= 0 {
   124  		return nil
   125  	}
   126  
   127  	pts := make([]*Point, 0, count)
   128  
   129  	for i := 0; i < count; i++ {
   130  		pts = append(pts, r.doRand())
   131  	}
   132  
   133  	return pts
   134  }
   135  
   136  func randStr(n int) string {
   137  	return cliutils.CreateRandomString(n)
   138  }
   139  
   140  func (r *ptRander) getFieldKey(i int) string {
   141  	if r.fixedKeys {
   142  		return r.fieldKeys[i]
   143  	} else {
   144  		return randStr(r.keyLen)
   145  	}
   146  }
   147  
   148  func (r *ptRander) randTags() KVs {
   149  	var kvs KVs
   150  	for i := 0; i < r.ntags; i++ {
   151  		var key, val string
   152  
   153  		switch {
   154  		case r.fixedTags:
   155  			key = r.tagKeys[i]
   156  			val = r.tagVals[i]
   157  
   158  		case r.fixedKeys:
   159  			key = r.tagKeys[i]
   160  			val = randStr(r.valLen)
   161  		default:
   162  			key = randStr(r.keyLen)
   163  			val = randStr(r.valLen)
   164  		}
   165  
   166  		if defaultPTPool == nil {
   167  			kvs = kvs.MustAddTag(key, val)
   168  		} else {
   169  			kv := defaultPTPool.GetKV(key, val)
   170  			kv.IsTag = true
   171  			kvs = kvs.AddKV(kv, true)
   172  		}
   173  	}
   174  
   175  	// add extra tags
   176  	// nolint: exhaustive
   177  	switch r.cat {
   178  	case Object, CustomObject:
   179  		// add `name` tag
   180  		key, val := "name", randStr(r.valLen)
   181  
   182  		if defaultPTPool == nil {
   183  			kvs = kvs.MustAddTag(key, val)
   184  		} else {
   185  			kv := defaultPTPool.GetKV(key, val)
   186  			kv.IsTag = true
   187  			kvs = kvs.AddKV(kv, true)
   188  		}
   189  	default:
   190  		// TODO:
   191  	}
   192  
   193  	return kvs
   194  }
   195  
   196  func (r *ptRander) randFields() KVs {
   197  	var kvs KVs
   198  
   199  	for i := 0; i < r.nfields; i++ {
   200  		var (
   201  			key = r.getFieldKey(i)
   202  			val any
   203  		)
   204  
   205  		switch i {
   206  		case 1:
   207  			val = mrand.Float64()
   208  
   209  		case 2:
   210  			val = mrand.Float32()
   211  
   212  		case 3, 4, 5:
   213  			if r.stringValues {
   214  				val = randStr(r.valLen)
   215  			} else {
   216  				continue
   217  			}
   218  
   219  		case 6, 7:
   220  			val = (i%2 == 0) // bool
   221  
   222  		default:
   223  			val = mrand.Int63()
   224  		}
   225  
   226  		if defaultPTPool == nil {
   227  			kvs = kvs.Add(key, val, false, true) // force set field
   228  		} else {
   229  			kv := defaultPTPool.GetKV(key, val)
   230  			if kv == nil {
   231  				panic(fmt.Sprintf("get nil kv on %q: %v", key, val))
   232  			}
   233  			kvs = kvs.AddKV(kv, true)
   234  		}
   235  	}
   236  
   237  	// add long text field
   238  	if len(r.sampleText) > 0 {
   239  		for i := 0; i < r.ntext; i++ {
   240  			key := "long-text" + randStr((i%r.keyLen)+1)
   241  			val := r.sampleText[mrand.Int63()%int64(len(r.sampleText))]
   242  
   243  			if defaultPTPool == nil {
   244  				kvs = kvs.Add(key, val, false, true)
   245  			} else {
   246  				kvs = kvs.AddKV(defaultPTPool.GetKV(key, val), true)
   247  			}
   248  		}
   249  	}
   250  
   251  	return kvs
   252  }
   253  
   254  func (r *ptRander) doRand() *Point {
   255  	var ptName string
   256  	if r.measurePrefix != "" {
   257  		ptName = r.measurePrefix + randStr(r.keyLen)
   258  	} else {
   259  		ptName = randStr(r.keyLen)
   260  	}
   261  
   262  	kvs := append(r.randTags(), r.randFields()...)
   263  	pt := NewPointV2(ptName, kvs, WithTime(r.ts), WithKeySorted(r.kvSorted))
   264  
   265  	if r.pb {
   266  		pt.SetFlag(Ppb)
   267  	}
   268  
   269  	return pt
   270  }