Recipes
Go SDK
5min
1. use amberflo api-key
Go
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "os"
7 "time"
8
9 "github.com/amberflo/metering-go/v2"
10 "github.com/rs/zerolog"
11 "github.com/xtgo/uuid"
12)
13
14func main() {
15 //obtain your Amberflo API Key
16 apiKey := "my-api-key"

2. setup the metering client
Go
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "os"
7 "time"
8
9 "github.com/amberflo/metering-go/v2"
10 "github.com/rs/zerolog"
11 "github.com/xtgo/uuid"
12)
13
14func main() {
15 //obtain your Amberflo API Key
16 apiKey := "my-api-key"
17
18 //Optional ingest options
19 //Frequency at which queued data will be sent to API. Default is 1 second.
20 intervalSeconds := 30 * time.Second
21 //Number of messages posted to the API. Default is 100.
22 batchSize := 5
23 //Debug mode logging. Default is false.
24 debug := true
25
26 //Instantiate a new metering client
27 meteringClient := metering.NewMeteringClient(
28 apiKey,
29 metering.WithBatchSize(batchSize),
30 metering.WithIntervalSeconds(intervalSeconds),
31 metering.WithDebug(debug),
32 )

3. ingest meters
Go
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "os"
7 "time"
8
9 "github.com/amberflo/metering-go/v2"
10 "github.com/rs/zerolog"
11 "github.com/xtgo/uuid"
12)
13
14func main() {
15 //obtain your Amberflo API Key
16 apiKey := "my-api-key"
17
18 //Optional ingest options
19 //Frequency at which queued data will be sent to API. Default is 1 second.
20 intervalSeconds := 30 * time.Second
21 //Number of messages posted to the API. Default is 100.
22 batchSize := 5
23 //Debug mode logging. Default is false.
24 debug := true
25
26 //Instantiate a new metering client
27 meteringClient := metering.NewMeteringClient(
28 apiKey,
29 metering.WithBatchSize(batchSize),
30 metering.WithIntervalSeconds(intervalSeconds),
31 metering.WithDebug(debug),
32 )
33
34 //Define dimesions for your meters. Dimensions can be used as filters.
35 dimensions := make(map[string]string)
36 dimensions["region"] = "Midwest"
37 dimensions["customerType"] = "Tech"
38
39 for i := 0; i < 50; i++ {
40 utcMillis := time.Now().UnixNano() / int64(time.Millisecond)
41 //Queue meter messages for ingestion.
42 //Queue will be flushed asyncrhonously when Metering.BatchSize is exceeded
43 //or periodically at Metering.IntervalSeconds
44 //unique ID is optional, but setting it
45 //helps with de-dupe and revoking an ingested meter
46 uniqueId := uuid.NewRandom().String()
47 meteringError := meteringClient.Meter(&metering.MeterMessage{
48 UniqueId: uniqueId,
49 MeterApiName: "ApiCalls-From-Go",
50 CustomerId: "1234",
51 MeterValue: float64(i) + 234.0,
52 MeterTimeInMillis: utcMillis,
53 Dimensions: dimensions,
54 })
55 if meteringError != nil {
56 fmt.Println("Metering error: ", meteringError)
57 }
58 time.Sleep(500 * time.Millisecond)
59 }

4. shutdown metering client
Go
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "os"
7 "time"
8
9 "github.com/amberflo/metering-go/v2"
10 "github.com/rs/zerolog"
11 "github.com/xtgo/uuid"
12)
13
14func main() {
15 //obtain your Amberflo API Key
16 apiKey := "my-api-key"
17
18 //Optional ingest options
19 //Frequency at which queued data will be sent to API. Default is 1 second.
20 intervalSeconds := 30 * time.Second
21 //Number of messages posted to the API. Default is 100.
22 batchSize := 5
23 //Debug mode logging. Default is false.
24 debug := true
25
26 //Instantiate a new metering client
27 meteringClient := metering.NewMeteringClient(
28 apiKey,
29 metering.WithBatchSize(batchSize),
30 metering.WithIntervalSeconds(intervalSeconds),
31 metering.WithDebug(debug),
32 )
33
34 //Define dimesions for your meters. Dimensions can be used as filters.
35 dimensions := make(map[string]string)
36 dimensions["region"] = "Midwest"
37 dimensions["customerType"] = "Tech"
38
39 for i := 0; i < 50; i++ {
40 utcMillis := time.Now().UnixNano() / int64(time.Millisecond)
41 //Queue meter messages for ingestion.
42 //Queue will be flushed asyncrhonously when Metering.BatchSize is exceeded
43 //or periodically at Metering.IntervalSeconds
44 //unique ID is optional, but setting it
45 //helps with de-dupe and revoking an ingested meter
46 uniqueId := uuid.NewRandom().String()
47 meteringError := meteringClient.Meter(&metering.MeterMessage{
48 UniqueId: uniqueId,
49 MeterApiName: "ApiCalls-From-Go",
50 CustomerId: "1234",
51 MeterValue: float64(i) + 234.0,
52 MeterTimeInMillis: utcMillis,
53 Dimensions: dimensions,
54 })
55 if meteringError != nil {
56 fmt.Println("Metering error: ", meteringError)
57 }
58 time.Sleep(500 * time.Millisecond)
59 }
60
61 //Perform graceful shutdown
62 //Flush all messages in the queue, stop the timer, close all channels, and shutdown the client
63 meteringClient.Shutdown()
64}

5. query usage
Go
1func usage() {
2 //obtain your Amberflo API Key
3 apiKey := "my-api-key"
4
5 //initialize the usage client
6 usageClient := metering.NewUsageClient(apiKey)
7
8 //set the start time of the time range in Epoch seconds
9 startTimeInSeconds := (time.Now().UnixNano() / int64(time.Second)) - (24 * 60 * 60)
10 timeRange := &metering.TimeRange{
11 StartTimeInSeconds: startTimeInSeconds,
12 }
13
14 //specify the limit and sort order
15 take := &metering.Take{
16 Limit: 10,
17 IsAscending: true,
18 }
19
20 // Example 1: group by customers for a specific meter and all customers
21 // setup usage query params
22 // visit following link for description of payload:
23 // https://amberflo.readme.io/reference#usage
24 usageResult, err := usageClient.GetUsage(&metering.UsagePayload{
25 MeterApiName: "ApiCalls-From-Go",
26 Aggregation: metering.Sum,
27 TimeGroupingInterval: metering.Day,
28 GroupBy: []string{"customerId"},
29 TimeRange: timeRange,
30 })
31 fmt.Println("Usage by meterApiName in json format")
32 printUsageData(*usageResult, err)
33
34 //Example 2: filter for a meter for specific customer
35 //setup usage query params
36 filter := make(map[string]string)
37 filter["customerId"] = "1234"
38
39 usageResult, err = usageClient.GetUsage(&metering.UsagePayload{
40 MeterApiName: "ApiCalls-From-Go",
41 Aggregation: metering.Sum,
42 TimeGroupingInterval: metering.Day,
43 GroupBy: []string{"customerId"},
44 TimeRange: timeRange,
45 Filter: filter,
46 })
47 fmt.Println("Usage for meter for specific customer in json format")
48 printUsageData(*usageResult, err)
49}
50
51func printUsageData(usageResult metering.DetailedMeterAggregation, err error) {
52 if err != nil {
53 fmt.Println("Usage error: ", err)
54 return
55 }
56
57 jsonString, err := json.MarshalIndent(usageResult, "", " ")
58 if err != nil {
59 fmt.Println("Usage error: ", err)
60 return
61 }
62
63 fmt.Println(string(jsonString))
64}

6. create customer
Go
1func setupCustomer() {
2 //obtain your Amberflo API Key
3 apiKey := "my-api-key"
4 customerId := "dell-8"
5 //Automatically create customer in Stripe
6 //and add stripeId to traits
7 createCustomerInStripe := true
8
9 //Instantiate a new metering client
10 customerClient := metering.NewCustomerClient(apiKey)
11
12 //check if customer exists
13 customer, err := customerClient.GetCustomer(customerId)
14 if err != nil {
15 fmt.Println("Error getting customer details: ", err)
16 }
17
18 //setup customer
19 //Traits are optional. Traits can be used as filters or aggregation buckets.
20 if customer != nil {
21 //customer exists
22 //update properties
23 customer.CustomerName = "Dell 2"
24 } else {
25 //setup new customer
26 //Traits are optional. Traits can be used as filters or aggregation buckets.
27 traits := make(map[string]string)
28 traits["region"] = "us-west"
29 traits["customerType"] = "Tech"
30 customer = &metering.Customer{
31 CustomerId: customerId,
32 CustomerName: "Dell",
33 CustomerEmail: "[email protected]",
34 Traits: traits,
35 Enabled: true,
36 }
37 }
38
39 customer, err = customerClient.AddorUpdateCustomer(customer, createCustomerInStripe)
40 if err != nil {
41 fmt.Println("Error creating customer details: ", err)
42 }
43
44 customerStatus := fmt.Sprintf("Stripe id for customer: %s", customer.Traits[metering.StripeTraitKey])
45 fmt.Println(customerStatus)
46}

7. define custom logger
Go
1type CustomLogger struct {
2 logger *zerolog.Logger
3}
4
5func NewCustomLogger() *CustomLogger {
6 logLevel := zerolog.DebugLevel
7 zerolog.SetGlobalLevel(logLevel)
8 logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
9 return &CustomLogger{logger: &logger}
10}
11
12func (l *CustomLogger) Log(args ...interface{}) {
13 msg := fmt.Sprintln(args...)
14 l.logger.Debug().Msg(msg)
15}
16
17func (l *CustomLogger) Logf(format string, args ...interface{}) {
18 l.logger.Debug().Msgf(format, args...)
19}

8. inject custom logger
Go
1func createClientWithCustomerLogger() {
2 //obtain your Amberflo API Key
3 apiKey := "my-api-key"
4 customerLogger := NewCustomLogger()
5
6 //Instantiate a new metering client with custom logger
7 Metering := metering.NewMeteringClient(
8 apiKey,
9 metering.WithLogger(customerLogger),
10 )
11}

9. Query usage cost
Go
1func queryUsageCost(){
2 //obtain your Amberflo API Key
3 apiKey := "my-api-key"
4
5 customerId := "dell-8"
6
7 //initialize the usage cost client
8 usageCostClient := metering.NewUsageCostClient(apiKey)
9
10 //set the start time of the time range in Epoch seconds
11 startTimeInSeconds := (time.Now().UnixNano() / int64(time.Second)) - (24 * 60 * 60)
12 timeRange := &metering.TimeRange{
13 StartTimeInSeconds: startTimeInSeconds,
14 }
15
16 //specify the limit and sort order
17 takeForCost := &metering.Take{
18 Limit: 10,
19 IsAscending: false,
20 }
21
22 // Example 1: group by customers
23 // setup usage cost query params
24 // visit following link for description of payload:
25 // https://docs.amberflo.io/reference/post_payments-cost-usage-cost
26 usageCostResult, err := usageCostClient.GetUsageCost(&metering.UsageCostsKey{
27 TimeGroupingInterval: metering.Day,
28 GroupBy: []string{"product_plan_id"},
29 TimeRange: timeRange,
30 Take: takeForCost,
31 })
32 fmt.Println("Usage Cost Result")
33 printUsageCostData(*usageCostResult, err)
34
35 //Example 2: filter for a cost for specific customer
36 //setup usage query params
37 filterForCost := make(map[string][]string)
38 filterForCost["customerId"] = []string{customerId}
39
40 usageCostResult, err = usageCostClient.GetUsageCost(&metering.UsageCostsKey{
41 TimeGroupingInterval: metering.Day,
42 GroupBy: []string{"product_plan_id"},
43 TimeRange: timeRange,
44 Take: takeForCost,
45 Filters: filterForCost,
46 })
47 fmt.Println("Usage cost for specific customer")
48 printUsageCostData(*usageCostResult, err)
49}
50
51func printUsageCostData(usageCostResult metering.UsageCosts, err error) {
52 if err != nil {
53 fmt.Println("Usage cost error: ", err)
54 return
55 }
56
57 jsonString, err := json.MarshalIndent(usageCostResult, "", " ")
58 if err != nil {
59 fmt.Println("Usage cost error: ", err)
60 return
61 }
62
63 fmt.Println(string(jsonString))
64}


Updated 11 Sep 2024
Did this page help you?