Skip to content

DOCSP-46497 & DOCSP-46233: Add historical and line item billing examples to Go SDK project #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 9, 2025
Merged
58 changes: 34 additions & 24 deletions generated-usage-examples/go/atlas-sdk-go/main.snippet.get-logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,67 @@ import (
"context"
"fmt"
"log"
"os"
"path/filepath"
"time"

"github.com/joho/godotenv"
"go.mongodb.org/atlas-sdk/v20250219001/admin"

"atlas-sdk-go/internal"
"atlas-sdk-go/internal/auth"
"atlas-sdk-go/internal/config"
"atlas-sdk-go/internal/errors"
"atlas-sdk-go/internal/fileutils"
"atlas-sdk-go/internal/logs"

"github.com/joho/godotenv"
"go.mongodb.org/atlas-sdk/v20250219001/admin"
)

func main() {
_ = godotenv.Load()
if err := godotenv.Load(); err != nil {
log.Printf("Warning: .env file not loaded: %v", err)
}

secrets, cfg, err := config.LoadAll("configs/config.json")
if err != nil {
log.Fatalf("config load: %v", err)
errors.ExitWithError("Failed to load configuration", err)
}

sdk, err := auth.NewClient(cfg, secrets)
client, err := auth.NewClient(cfg, secrets)
if err != nil {
log.Fatalf("client init: %v", err)
errors.ExitWithError("Failed to initialize authentication client", err)
}

ctx := context.Background()

// Fetch logs with the provided parameters
p := &admin.GetHostLogsApiParams{
GroupId: cfg.ProjectID,
HostName: cfg.HostName,
LogName: "mongodb",
}
ts := time.Now().Format("20060102_150405")
base := fmt.Sprintf("%s_%s_%s", p.HostName, p.LogName, ts)
outDir := "logs"
os.MkdirAll(outDir, 0o755)
gzPath := filepath.Join(outDir, base+".gz")
txtPath := filepath.Join(outDir, base+".txt")
rc, err := logs.FetchHostLogs(ctx, client.MonitoringAndLogsApi, p)
if err != nil {
errors.ExitWithError("Failed to fetch logs", err)
}
defer fileutils.SafeClose(rc)

rc, err := logs.FetchHostLogs(ctx, sdk.MonitoringAndLogsApi, p)
// Prepare output paths
outDir := "logs"
prefix := fmt.Sprintf("%s_%s", p.HostName, p.LogName)
gzPath, err := fileutils.GenerateOutputPath(outDir, prefix, "gz")
if err != nil {
errors.ExitWithError("Failed to generate GZ output path", err)
}
txtPath, err := fileutils.GenerateOutputPath(outDir, prefix, "txt")
if err != nil {
log.Fatalf("download logs: %v", err)
errors.ExitWithError("Failed to generate TXT output path", err)
}
defer internal.SafeClose(rc)

if err := logs.WriteToFile(rc, gzPath); err != nil {
log.Fatalf("save gz: %v", err)
// Save compressed logs
if err := fileutils.WriteToFile(rc, gzPath); err != nil {
errors.ExitWithError("Failed to save compressed logs", err)
}
fmt.Println("Saved compressed log to", gzPath)

if err := logs.DecompressGzip(gzPath, txtPath); err != nil {
log.Fatalf("decompress: %v", err)
// Decompress logs
if err := fileutils.DecompressGzip(gzPath, txtPath); err != nil {
errors.ExitWithError("Failed to decompress logs", err)
}
fmt.Println("Uncompressed log to", txtPath)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,33 @@ import (
"fmt"
"log"

"github.com/joho/godotenv"
"go.mongodb.org/atlas-sdk/v20250219001/admin"

"atlas-sdk-go/internal/auth"
"atlas-sdk-go/internal/config"
"atlas-sdk-go/internal/errors"
"atlas-sdk-go/internal/metrics"

"github.com/joho/godotenv"
"go.mongodb.org/atlas-sdk/v20250219001/admin"
)

func main() {
_ = godotenv.Load()
if err := godotenv.Load(); err != nil {
log.Printf("Warning: .env file not loaded: %v", err)
}

secrets, cfg, err := config.LoadAll("configs/config.json")
if err != nil {
log.Fatalf("config load: %v", err)
errors.ExitWithError("Failed to load configuration", err)
}

sdk, err := auth.NewClient(cfg, secrets)
client, err := auth.NewClient(cfg, secrets)
if err != nil {
log.Fatalf("client init: %v", err)
errors.ExitWithError("Failed to initialize authentication client", err)
}

ctx := context.Background()

// Fetch disk metrics with the provided parameters
p := &admin.GetDiskMeasurementsApiParams{
GroupId: cfg.ProjectID,
ProcessId: cfg.ProcessID,
Expand All @@ -36,13 +42,16 @@ func main() {
Granularity: admin.PtrString("P1D"),
Period: admin.PtrString("P1D"),
}

view, err := metrics.FetchDiskMetrics(ctx, sdk.MonitoringAndLogsApi, p)
view, err := metrics.FetchDiskMetrics(ctx, client.MonitoringAndLogsApi, p)
if err != nil {
log.Fatalf("disk metrics: %v", err)
errors.ExitWithError("Failed to fetch disk metrics", err)
}

out, _ := json.MarshalIndent(view, "", " ")
// Output metrics
out, err := json.MarshalIndent(view, "", " ")
if err != nil {
errors.ExitWithError("Failed to format metrics data", err)
}
fmt.Println(string(out))
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,35 @@ import (
"fmt"
"log"

"github.com/joho/godotenv"
"go.mongodb.org/atlas-sdk/v20250219001/admin"
"atlas-sdk-go/internal/errors"

"atlas-sdk-go/internal/auth"
"atlas-sdk-go/internal/config"

"github.com/joho/godotenv"
"go.mongodb.org/atlas-sdk/v20250219001/admin"

"atlas-sdk-go/internal/metrics"
)

func main() {
_ = godotenv.Load()
if err := godotenv.Load(); err != nil {
log.Printf("Warning: .env file not loaded: %v", err)
}

secrets, cfg, err := config.LoadAll("configs/config.json")
if err != nil {
log.Fatalf("config load: %v", err)
errors.ExitWithError("Failed to load configuration", err)
}

sdk, err := auth.NewClient(cfg, secrets)
client, err := auth.NewClient(cfg, secrets)
if err != nil {
log.Fatalf("client init: %v", err)
errors.ExitWithError("Failed to initialize authentication client", err)
}

ctx := context.Background()

// Fetch process metrics with the provided parameters
p := &admin.GetHostMeasurementsApiParams{
GroupId: cfg.ProjectID,
ProcessId: cfg.ProcessID,
Expand All @@ -42,12 +50,16 @@ func main() {
Period: admin.PtrString("P7D"),
}

view, err := metrics.FetchProcessMetrics(ctx, sdk.MonitoringAndLogsApi, p)
view, err := metrics.FetchProcessMetrics(ctx, client.MonitoringAndLogsApi, p)
if err != nil {
log.Fatalf("process metrics: %v", err)
errors.ExitWithError("Failed to fetch process metrics", err)
}

out, _ := json.MarshalIndent(view, "", " ")
// Output metrics
out, err := json.MarshalIndent(view, "", " ")
if err != nil {
errors.ExitWithError("Failed to format metrics data", err)
}
fmt.Println(string(out))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// See entire project at https://github.com/mongodb/atlas-architecture-go-sdk
package main

import (
"context"
"fmt"
"log"
"time"

"atlas-sdk-go/internal/auth"
"atlas-sdk-go/internal/billing"
"atlas-sdk-go/internal/config"
"atlas-sdk-go/internal/data/export"
"atlas-sdk-go/internal/errors"
"atlas-sdk-go/internal/fileutils"

"github.com/joho/godotenv"
"go.mongodb.org/atlas-sdk/v20250219001/admin"
)

func main() {
if err := godotenv.Load(); err != nil {
log.Printf("Warning: .env file not loaded: %v", err)
}

secrets, cfg, err := config.LoadAll("configs/config.json")
if err != nil {
errors.ExitWithError("Failed to load configuration", err)
}

client, err := auth.NewClient(cfg, secrets)
if err != nil {
errors.ExitWithError("Failed to initialize authentication client", err)
}

ctx := context.Background()
p := &admin.ListInvoicesApiParams{
OrgId: cfg.OrgID,
}

fmt.Printf("Fetching historical invoices for organization: %s\n", p.OrgId)

// Fetch invoices from the previous six months with the provided options
invoices, err := billing.ListInvoicesForOrg(ctx, client.InvoicesApi, p,
billing.WithViewLinkedInvoices(true),
billing.WithIncludeCount(true),
billing.WithDateRange(time.Now().AddDate(0, -6, 0), time.Now()))
if err != nil {
errors.ExitWithError("Failed to retrieve invoices", err)
}

if invoices.GetTotalCount() > 0 {
fmt.Printf("Total count of invoices: %d\n", invoices.GetTotalCount())
} else {
fmt.Println("No invoices found for the specified date range")
return
}

// Export invoice data to be used in other systems or for reporting
outDir := "invoices"
prefix := fmt.Sprintf("historical_%s", p.OrgId)

exportInvoicesToJSON(invoices, outDir, prefix)
exportInvoicesToCSV(invoices, outDir, prefix)
}

func exportInvoicesToJSON(invoices *admin.PaginatedApiInvoiceMetadata, outDir, prefix string) {
jsonPath, err := fileutils.GenerateOutputPath(outDir, prefix, "json")
if err != nil {
errors.ExitWithError("Failed to generate JSON output path", err)
}
if err := export.ToJSON(invoices.GetResults(), jsonPath); err != nil {
errors.ExitWithError("Failed to write JSON file", err)
}
fmt.Printf("Exported invoice data to %s\n", jsonPath)
}

func exportInvoicesToCSV(invoices *admin.PaginatedApiInvoiceMetadata, outDir, prefix string) {
csvPath, err := fileutils.GenerateOutputPath(outDir, prefix, "csv")
if err != nil {
errors.ExitWithError("Failed to generate CSV output path", err)
}

// Set the headers and mapped rows for the CSV export
headers := []string{"InvoiceID", "Status", "Created", "AmountBilled"}
err = export.ToCSVWithMapper(invoices.GetResults(), csvPath, headers, func(invoice admin.BillingInvoiceMetadata) []string {
return []string{
invoice.GetId(),
invoice.GetStatusName(),
invoice.GetCreated().Format(time.RFC3339),
fmt.Sprintf("%.2f", float64(invoice.GetAmountBilledCents())/100.0),
}
})
if err != nil {
errors.ExitWithError("Failed to write CSV file", err)
}

fmt.Printf("Exported invoice data to %s\n", csvPath)
}

Loading