package main import ( "flag" "fmt" "log" "math/rand/v2" "os" "time" "gopkg.in/ini.v1" "gordenko.dev/dima/qb/client" "gordenko.dev/dima/qb/proto" ) var ( metricTypeToName = []string{ "", "cumulative", "instant", } ) func main() { var ( iniFileName string ) flag.Usage = func() { fmt.Fprint(flag.CommandLine.Output(), helpMessage) fmt.Fprint(flag.CommandLine.Output(), configExample) fmt.Fprintf(flag.CommandLine.Output(), mainUsage, os.Args[0]) flag.PrintDefaults() } flag.StringVar(&iniFileName, "c", "requests.ini", "path to *.ini config file") flag.Parse() config, err := loadConfig(iniFileName) if err != nil { log.Fatalln(err) } conn, err := client.Connect(config.DatabaseAddr) if err != nil { log.Fatalf("client.Connect(%s): %s\n", config.DatabaseAddr, err) } else { fmt.Println("Connected to database") } sendRequests(conn) } // CONFIG FILE const mainUsage = `Usage: %s -c path/to/config.ini ` const helpMessage = `Gordenko project. Example requests. Version: 1.0 created by Dmytro Gordenko, 1.e4.kc6@gmail.com ` const configExample = ` requests.ini example: databaseAddr = :12345 ` type Config struct { DatabaseAddr string } func (s Config) String() string { return fmt.Sprintf(`starting options: databaseAddr = %s `, s.DatabaseAddr) } func loadConfig(iniFileName string) (_ Config, err error) { file, err := ini.Load(iniFileName) if err != nil { return } conf := Config{} top := file.Section("") conf.DatabaseAddr = top.Key("databaseAddr").String() return conf, nil } func sendRequests(conn *client.Connection) { var ( //instantMetricID uint32 = 10000 cumulativeMetricID uint32 = 10001 fracDigits byte = 2 err error ) _ = cumulativeMetricID _ = fracDigits //conn.DeleteMetric(instantMetricID) //conn.DeleteMetric(cumulativeMetricID) // ADD INSTANT METRIC // err = conn.AddMetric(proto.AddMetricReq{ // MetricID: cumulativeMetricID, // MetricType: qb.Instant, // FracDigits: fracDigits, // }) // if err != nil { // log.Fatalf("conn.AddMetric: %s\n", err) // } else { // fmt.Printf("\nInstant metric %d added\n", cumulativeMetricID) // } // GET INSTANT METRIC // iMetric, err := conn.GetMetric(cumulativeMetricID) // if err != nil { // log.Fatalf("conn.GetMetric: %s\n", err) // } else { // fmt.Printf(` // GetMetric: // metricID: %d // metricType: %s // fracDigits: %d // `, // iMetric.MetricID, metricTypeToName[iMetric.MetricType], fracDigits) // } // APPEND MEASURES // instantMeasures := GenerateInstantMeasures(62, 220) // err = conn.AppendMeasures(proto.AppendMeasuresReq{ // MetricID: instantMetricID, // Measures: instantMeasures, // }) // if err != nil { // log.Fatalf("conn.AppendMeasures: %s\n", err) // } else { // fmt.Printf("\nAppended %d measures for the metric %d\n", // len(instantMeasures), instantMetricID) // } // // LIST INSTANT MEASURES // lastTimestamp := instantMeasures[len(instantMeasures)-1].Timestamp // until := time.Unix(int64(lastTimestamp), 0) // since := until.Add(-5 * time.Hour) // instantList, err := conn.ListInstantMeasures(proto.ListInstantMeasuresReq{ // MetricID: instantMetricID, // Since: uint32(since.Unix()), // Until: uint32(until.Unix()), // }) // if err != nil { // log.Fatalf("conn.ListInstantMeasures: %s\n", err) // } else { // fmt.Printf("\nListInstantMeasures %s - %s:\n", // formatTime(uint32(since.Unix())), formatTime(uint32(until.Unix()))) // for _, item := range instantList { // fmt.Printf(" %s => %.2f\n", formatTime(item.Timestamp), item.Value) // } // } // // LIST ALL INSTANT MEASURES // instantList, err = conn.ListAllInstantMeasures(instantMetricID) // if err != nil { // log.Fatalf("conn.ListAllInstantMeasures: %s\n", err) // } else { // fmt.Printf("\nListAllInstantMeasures (last 15 items):\n") // for _, item := range instantList[:15] { // fmt.Printf(" %s => %.2f\n", formatTime(item.Timestamp), item.Value) // } // } // // LIST INSTANT PERIODS (group by hour) // until = time.Unix(int64(lastTimestamp+1), 0) // since = until.Add(-24 * time.Hour) // instantPeriods, err := conn.ListInstantPeriods(proto.ListInstantPeriodsReq{ // MetricID: instantMetricID, // Since: proto.TimeBound{ // Year: since.Year(), // Month: since.Month(), // Day: since.Day(), // }, // Until: proto.TimeBound{ // Year: until.Year(), // Month: until.Month(), // Day: until.Day(), // }, // GroupBy: qb.GroupByHour, // AggregateFuncs: qb.AggregateMin | qb.AggregateMax | qb.AggregateAvg, // }) // if err != nil { // log.Fatalf("conn.ListInstantPeriods: %s\n", err) // } else { // fmt.Printf("\nListInstantPeriods (1 day, group by hour):\n") // for _, item := range instantPeriods { // fmt.Printf(" %s => min %.2f, max %.2f, avg %.2f\n", formatHourPeriod(item.Period), item.Min, item.Max, item.Avg) // } // } // // LIST INSTANT PERIODS (group by day) // until = time.Unix(int64(lastTimestamp+1), 0) // since = until.AddDate(0, 0, -7) // instantPeriods, err = conn.ListInstantPeriods(proto.ListInstantPeriodsReq{ // MetricID: instantMetricID, // Since: proto.TimeBound{ // Year: since.Year(), // Month: since.Month(), // Day: since.Day(), // }, // Until: proto.TimeBound{ // Year: until.Year(), // Month: until.Month(), // Day: until.Day(), // }, // GroupBy: qb.GroupByDay, // AggregateFuncs: qb.AggregateMin | qb.AggregateMax | qb.AggregateAvg, // }) // if err != nil { // log.Fatalf("conn.ListInstantPeriods: %s\n", err) // } else { // fmt.Printf("\nListInstantPeriods (7 days, group by day):\n") // for _, item := range instantPeriods { // fmt.Printf(" %s => min %.2f, max %.2f, avg %.2f\n", formatDayPeriod(item.Period), item.Min, item.Max, item.Avg) // } // } // // LIST INSTANT PERIODS (group by month) // until = time.Unix(int64(lastTimestamp+1), 0) // since = until.AddDate(0, 0, -62) // instantPeriods, err = conn.ListInstantPeriods(proto.ListInstantPeriodsReq{ // MetricID: instantMetricID, // Since: proto.TimeBound{ // Year: since.Year(), // Month: since.Month(), // Day: since.Day(), // }, // Until: proto.TimeBound{ // Year: until.Year(), // Month: until.Month(), // Day: until.Day(), // }, // GroupBy: qb.GroupByMonth, // AggregateFuncs: qb.AggregateMin | qb.AggregateMax | qb.AggregateAvg, // }) // if err != nil { // log.Fatalf("conn.ListInstantPeriods: %s\n", err) // } else { // fmt.Printf("\nListInstantPeriods (62 days, group by month):\n") // for _, item := range instantPeriods { // fmt.Printf(" %s => min %.2f, max %.2f, avg %.2f\n", formatMonthPeriod(item.Period), item.Min, item.Max, item.Avg) // } // } // // DELETE INSTANT METRIC MEASURES // err = conn.DeleteMeasures(proto.DeleteMeasuresReq{ // MetricID: instantMetricID, // }) // if err != nil { // log.Fatalf("conn.DeleteMeasures: %s\n", err) // } else { // fmt.Printf("\nInstant metric %d measures deleted\n", instantMetricID) // } // // DELETE INSTANT METRIC // err = conn.DeleteMetric(instantMetricID) // if err != nil { // log.Fatalf("conn.DeleteMetric: %s\n", err) // } else { // fmt.Printf("\nInstant metric %d deleted\n", instantMetricID) // } // ADD CUMULATIVE METRIC // err = conn.AddMetric(proto.AddMetricReq{ // MetricID: cumulativeMetricID, // MetricType: qb.Cumulative, // FracDigits: fracDigits, // }) // if err != nil { // log.Fatalf("conn.AddMetric: %s\n", err) // } else { // fmt.Printf("\nCumulative metric %d added\n", cumulativeMetricID) // } // GET CUMULATIVE METRIC cMetric, err := conn.GetMetric(cumulativeMetricID) if err != nil { log.Fatalf("conn.GetMetric: %s\n", err) } else { fmt.Printf(` GetMetric: metricID: %d metricType: %s fracDigits: %d `, cMetric.MetricID, metricTypeToName[cMetric.MetricType], cMetric.FracDigits) } // APPEND MEASURES // cumulativeMeasures := GenerateCumulativeMeasures(200) // if len(cumulativeMeasures) > 65535 { // cumulativeMeasures = cumulativeMeasures[:65535] // } // result, err := conn.AppendMeasures(proto.AppendMeasuresReq{ // MetricID: cumulativeMetricID, // Measures: cumulativeMeasures, // }) // if err != nil { // log.Fatalf("conn.AppendMeasures: %s\n", err) // } else { // fmt.Printf("\nAppended %d measures for the metric %d: count=%d, errorCode=%d\n", // len(cumulativeMeasures), cumulativeMetricID, result.WrittenCount, result.ErrorCode) // } // currentValues, err := conn.ListCurrentValues([]uint32{ // cumulativeMetricID, // }) // if err != nil { // log.Fatalf("conn.ListCurrentValues: %s\n", err) // } else { // for _, v := range currentValues { // fmt.Println(v.MetricID, v.Timestamp, v.Value) // } // } // LIST CUMULATIVE MEASURES // lastTimestamp = cumulativeMeasures[len(cumulativeMeasures)-1].Timestamp // until = time.Unix(int64(lastTimestamp), 0) // since = until.Add(-5 * time.Hour) // cumulativeList, err := conn.ListCumulativeMeasures(proto.ListCumulativeMeasuresReq{ // MetricID: cumulativeMetricID, // Since: uint32(since.Unix()), // Until: uint32(until.Unix()), // }) // if err != nil { // log.Fatalf("conn.ListCumulativeMeasures: %s\n", err) // } else { // fmt.Printf("\nListCumulativeMeasures %s - %s:\n", // formatTime(uint32(since.Unix())), formatTime(uint32(until.Unix()))) // for _, item := range cumulativeList { // fmt.Printf(" %s => %.2f\n", formatTime(item.Timestamp), item.Value) // } // } // LIST ALL CUMULATIVE MEASURES var cumulativeList []proto.CumulativeMeasure cumulativeList, err = conn.ListAllCumulativeMeasures(cumulativeMetricID) if err != nil { log.Fatalf("conn.ListAllCumulativeMeasures: %s\n", err) } else { fmt.Printf("\nListAllCumulativeMeasures (last 15 items):\n") //fmt.Printf("%#v\n", cumulativeList) for idx, item := range cumulativeList { fmt.Printf(" %d: %s => %.2f\n", idx, formatTime(item.Timestamp), item.Value) } } // // LIST CUMULATIVE PERIODS (group by hour) // until = time.Unix(int64(lastTimestamp+1), 0) // since = until.Add(-24 * time.Hour) // cumulativePeriods, err := conn.ListCumulativePeriods(proto.ListCumulativePeriodsReq{ // MetricID: cumulativeMetricID, // Since: proto.TimeBound{ // Year: since.Year(), // Month: since.Month(), // Day: since.Day(), // }, // Until: proto.TimeBound{ // Year: until.Year(), // Month: until.Month(), // Day: until.Day(), // }, // GroupBy: qb.GroupByHour, // }) // if err != nil { // log.Fatalf("conn.ListCumulativePeriods: %s\n", err) // } else { // fmt.Printf("\nListCumulativePeriods (1 day, group by hour):\n") // for _, item := range cumulativePeriods { // fmt.Printf(" %s => end value %.2f, total %.2f\n", formatHourPeriod(item.Period), item.EndValue, item.Total) // } // } // // LIST CUMULATIVE PERIODS (group by day) // until = time.Unix(int64(lastTimestamp+1), 0) // since = until.AddDate(0, 0, -7) // cumulativePeriods, err = conn.ListCumulativePeriods(proto.ListCumulativePeriodsReq{ // MetricID: cumulativeMetricID, // Since: proto.TimeBound{ // Year: since.Year(), // Month: since.Month(), // Day: since.Day(), // }, // Until: proto.TimeBound{ // Year: until.Year(), // Month: until.Month(), // Day: until.Day(), // }, // GroupBy: qb.GroupByDay, // }) // if err != nil { // log.Fatalf("conn.ListCumulativePeriods: %s\n", err) // } else { // fmt.Printf("\nListCumulativePeriods (7 days, group by day):\n") // for _, item := range cumulativePeriods { // fmt.Printf(" %s => end value %.2f, total %.2f\n", formatDayPeriod(item.Period), item.EndValue, item.Total) // } // } // // LIST CUMULATIVE PERIODS (group by day) // until = time.Unix(int64(lastTimestamp+1), 0) // since = until.AddDate(0, 0, -62) // cumulativePeriods, err = conn.ListCumulativePeriods(proto.ListCumulativePeriodsReq{ // MetricID: cumulativeMetricID, // Since: proto.TimeBound{ // Year: since.Year(), // Month: since.Month(), // Day: since.Day(), // }, // Until: proto.TimeBound{ // Year: until.Year(), // Month: until.Month(), // Day: until.Day(), // }, // GroupBy: qb.GroupByMonth, // }) // if err != nil { // log.Fatalf("conn.ListCumulativePeriods: %s\n", err) // } else { // fmt.Printf("\nListCumulativePeriods (62 days, group by month):\n") // for _, item := range cumulativePeriods { // fmt.Printf(" %s => end value %.2f, total %.2f\n", formatMonthPeriod(item.Period), item.EndValue, item.Total) // } // } // // DELETE CUMULATIVE METRIC MEASURES // err = conn.DeleteMeasures(proto.DeleteMeasuresReq{ // MetricID: cumulativeMetricID, // }) // if err != nil { // log.Fatalf("conn.DeleteMeasures: %s\n", err) // } else { // fmt.Printf("\nCumulative metric %d measures deleted\n", cumulativeMetricID) // } // // DELETE CUMULATIVE METRIC // err = conn.DeleteMetric(cumulativeMetricID) // // if err != nil { // log.Fatalf("conn.DeleteMetric: %s\n", err) // } else { // // fmt.Printf("\nCumulative metric %d deleted\n", cumulativeMetricID) // } } const datetimeLayout = "2006-01-02 15:04:05" func formatTime(timestamp uint32) string { tm := time.Unix(int64(timestamp), 0) return tm.Format(datetimeLayout) } func formatHourPeriod(period uint32) string { tm := time.Unix(int64(period), 0) return tm.Format("2006-01-02 15:00 - 15") + ":59" } func formatDayPeriod(period uint32) string { tm := time.Unix(int64(period), 0) return tm.Format("2006-01-02") } func formatMonthPeriod(period uint32) string { tm := time.Unix(int64(period), 0) return tm.Format("2006-01") } func GenerateCumulativeMeasures(days int) []proto.Measure { var ( measures []proto.Measure minutes = []int{14, 29, 44, 59} hoursPerDay = 24 totalHours = days * hoursPerDay since = time.Now().AddDate(0, 0, -days) totalValue float64 ) idx := 0 for i := range totalHours { hourTime := since.Add(time.Duration(i) * time.Hour) for _, m := range minutes { measureTime := time.Date( hourTime.Year(), hourTime.Month(), hourTime.Day(), hourTime.Hour(), m, // minutes 0, // seconds 0, // nanoseconds time.Local, ) measure := proto.Measure{ Timestamp: uint32(measureTime.Unix()), Value: totalValue, } measures = append(measures, measure) totalValue += rand.Float64() if idx < 1500 { fmt.Println(idx, measure.Timestamp) } idx++ } } for i := 1; i < len(measures); i++ { if measures[i].Timestamp <= measures[i-1].Timestamp { fmt.Println("FUCK", i) } } return measures } func GenerateInstantMeasures(days int, baseValue float64) []proto.Measure { var ( measures []proto.Measure minutes = []int{14, 29, 44, 59} hoursPerDay = 24 totalHours = days * hoursPerDay since = time.Now().AddDate(0, 0, -days) ) for i := range totalHours { hourTime := since.Add(time.Duration(i) * time.Hour) for _, m := range minutes { measureTime := time.Date( hourTime.Year(), hourTime.Month(), hourTime.Day(), hourTime.Hour(), m, // minutes 0, // seconds 0, // nanoseconds time.Local, ) // value = +-10% from base value fluctuation := baseValue * 0.1 value := baseValue + (rand.Float64()*2-1)*fluctuation measure := proto.Measure{ Timestamp: uint32(measureTime.Unix()), Value: value, } measures = append(measures, measure) } } return measures } //02 88 30 3e 88 31 1d 88 31 3e a3 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 28 68 05 6a //02 88 30 3e 88 31 1d 88 31 3e a3 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 28 68 05 6a //02 88 4b 4c 88 4c 06 88 4c 39 ae 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 30 1b 2c 6a //02 88 4b 4c 88 4c 06 88 4c 39 ae 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 7f 04 87 30 1b 2c 6a