moesifgin

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2024 License: Apache-2.0 Imports: 20 Imported by: 0

README

Moesif Middleware for Go Gin Framework

by Moesif, the API analytics and API monetization platform.

Built For Software License Source Code

Moesif middleware for Go Gin Framework logs API calls and sends them to Moesif for API analytics and log analysis. This middleware allows you to integrate Moesif's API analytics and API monetization features into your Go Gin applications with minimal configuration.

If you're new to Moesif, see our Getting Started resources to quickly get up and running.

Prerequisites

Before using this middleware, make sure you have the following:

Get Your Moesif Application ID

After you log into Moesif Portal, you can get your Moesif Application ID during the onboarding steps. You can always access the Application ID any time by following these steps from Moesif Portal after logging in:

  1. Select the account icon to bring up the settings menu.
  2. Select Installation or API Keys.
  3. Copy your Moesif Application ID from the Collector Application ID field.
Accessing the settings menu in Moesif Portal

Install the Middleware

Use go get with the version for Go modules

go get github.com/moesif/moesifgin@v1.0.0

Configure the Middleware

See the available configuration options to learn how to configure the middleware for your use case.

How to Use

The following snippet shows how to use the middleware:

import (
    "github.com/gin-gonic/gin"
    "github.com/moesif/moesifgin"
)

func main() {
    r := gin.New()

    moesifOptions := map[string]interface{}{
        "Application_Id":   "YOUR_MOESIF_APPLICATION_ID",
        "Log_Body":         true,
    }
    r.Use(moesifgin.MoesifMiddleware(moesifOptions))

    r.POST("/test", func(c *gin.Context) {
		c.JSON(201, gin.H{"message": "hello world"})
	})

    r.Run(":8080")
}

Replace YOUR_MOESIF_APPLICATION_ID with your Moesif Application ID.

Optional: Capturing Outgoing API Calls

In addition to your own APIs, you can also start capturing calls out to third-party services through the following method:

moesifgin.StartCaptureOutgoing(moesifOptions)
moesifOptions (Required)

A map[string]interface{} type containing the configuration options for your application. See the example application code for better understanding.

See Configuration Options for the common configuration options. See Options for Logging Outgoing Calls for configuration options specific to capturing and logging outgoing API calls.

Troubleshoot

For a general troubleshooting guide that can help you solve common problems, see Server Troubleshooting Guide.

Other troubleshooting supports:

Configuration Options

The following sections describe the available configuration options for this middleware. You can set these options in the Moesif initialization options object. See the example application code to understand how you can specify these options.

Application_Id (Required)
Data type
string

A string that identifies your application in Moesif.

Should_Skip
Data type Parameters Return type
Function (c *gin.Context) bool

Optional.

A function that takes a *gin.Context, and returns true if you want to skip logging this particular event.

Identify_User
Data type Parameters Return type
Function (c *gin.Context) string

Optional, but highly recommended.

A function that takes a *gin.Context, and returns a string that represents the user ID used by your system.

Moesif identifies users automatically. However, due to the differences arising from different frameworks and implementations, provide this function to ensure user identification properly.

Identify_Company
Data type Parameters Return type
Function (c *gin.Context) string

Optional.

A function that takes a *gin.Context, and returns a string that represents the company ID for this event.

Get_Metadata
Data type Parameters Return type
Function (c *gin.Context) map[string]interface{}

Optional.

A function that returns a map that allows you to add custom metadata that will be associated with the event.

The metadata must be a map that can be converted to JSON. For example, you may want to save a virtual machine instance ID, a trace ID, or a tenant ID with the request.

Get_Session_Token
Data type Parameters Return type
Function (c *gin.Context) string

Optional.

A function that takes a *gin.Context, and returns a string that represents the session token for this event.

Similar to users and companies, Moesif tries to retrieve session tokens automatically. But if it doesn't work for your service, provide this function to help identify sessions.

Request_Header_Masks
Data type Parameters Return type
Function () []string

Optional.

A function that returns an array of strings to mask specific request header fields.

Request_Body_Masks
Data type Parameters Return type
Function () []string

Optional.

A function that returns an array of strings to mask specific request body fields.

Response_Header_Masks
Data type Parameters Return type
Function () []string

Optional.

A function that returns an array of strings to mask specific response header fields.

Response_Body_Masks
Data type Parameters Return type
Function () []string

Optional.

A function that returns an array of strings to mask specific response body fields.

Debug
Data type
bool

Optional.

Set to true to see debugging messages. This may help you troubleshoot integration issues.

Log_Body
Data type Default
bool true

Optional.

Set to false to not log the request and response body to Moesif.

Event_Queue_Size
Data type Default
int 10000

An optional field name that specifies the maximum number of events to hold in queue before sending to Moesif. In case of network issues, the middleware may fail to connect to or send events to Moesif. For those scenarios, this option helps prevent adding new events to the queue to prevent memory overflow.

Batch_Size
Data type Default
int 200

An optional field name that specifies the maximum batch size when sending to Moesif.

Timer_Wake_Up_Seconds
Data type Default
int 2

An optional field that specifies a time in seconds how often background thread runs to send events to Moesif.

Options for Logging Outgoing Calls

The following configuration options apply to outgoing API calls. The request and response objects passed in are *http.Request and *http.Response objects of the Go standard library.

Should_Skip_Outgoing
Data type Parameters Return type
Function (req *http.Request, resp *http.Response) bool

Optional.

A function that takes a request and response, and returns true if you want to skip logging this particular event.

Identify_User_Outgoing
Data type Parameters Return type
Function (req *http.Request, resp *http.Response) string

Optional, but highly recommended.

A function that takes a request and response, and returns a string that represents the user ID used by your system.

Identify_Company_Outgoing
Data type Parameters Return type
Function (req *http.Request, resp *http.Response) string

Optional.

A function that takes a request and response, and returns a string that represents the company ID for this event.

Get_Metadata_Outgoing
Data type Parameters Return type
Function (req *http.Request, resp *http.Response) map[string]interface{}

Optional.

A function that returns a map that allows you to add custom metadata that will be associated with the event.

Get_Session_Token_Outgoing
Data type Parameters Return type
Function (req *http.Request, resp *http.Response) string

Optional.

A function that takes a request and response, and returns a string that represents the session token for this event.

Log_Body_Outgoing
Data type Default
bool true

Optional.

Set to false to not log the request and response body to Moesif.

Examples

The following examples demonstrate some common operations:

Update User

UpdateUser Method

Use this method to create or update a user profile in Moesif.

import (
    "github.com/moesif/moesifgin"
    "github.com/moesif/moesifapi-go/models"
)

func literalFieldValue(value string) *string {
    return &value
}

moesifOptions := map[string]interface{} {
    "Application_Id": "YOUR_MOESIF_APPLICATION_ID",
    "Log_Body": true,
}

// Campaign object is optional, but useful if you want to track ROI of acquisition channels
// See https://www.moesif.com/docs/api#users for campaign schema
campaign := models.CampaignModel {
  UtmSource: literalFieldValue("google"),
  UtmMedium: literalFieldValue("cpc"), 
  UtmCampaign: literalFieldValue("adwords"),
  UtmTerm: literalFieldValue("api+tooling"),
  UtmContent: literalFieldValue("landing"),
}
  
// metadata can be any custom map
metadata := map[string]interface{}{
  "email": "john@acmeinc.com",
  "first_name": "John",
  "last_name": "Doe",
  "title": "Software Engineer",
  "sales_info": map[string]interface{}{
      "stage": "Customer",
      "lifetime_value": 24000,
      "account_owner": "mary@contoso.com",
  },
}

// Only UserId is required
user := models.UserModel{
  UserId:    "12345",
  CompanyId: literalFieldValue("67890"), // If set, associate user with a company object
  Campaign:  &campaign,
  Metadata:  &metadata,
}

// Update User
moesifgin.UpdateUser(&user, moesifOptions)

The metadata field can contain any user demographic or other information you want to store.

Only the UserId field is required. This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.

UpdateUsersBatch Method

Similar to UpdateUser, but to update a list of users in one batch.

import (
    "github.com/moesif/moesifgin"
    "github.com/moesif/moesifapi-go/models"
)

func literalFieldValue(value string) *string {
    return &value
}

moesifOptions := map[string]interface{} {
    "Application_Id": "YOUR_MOESIF_APPLICATION_ID",
}

// List of Users
var users []*models.UserModel

// Campaign object is optional, but useful if you want to track ROI of acquisition channels
// See https://www.moesif.com/docs/api#users for campaign schema
campaign := models.CampaignModel {
  UtmSource: literalFieldValue("google"),
  UtmMedium: literalFieldValue("cpc"), 
  UtmCampaign: literalFieldValue("adwords"),
  UtmTerm: literalFieldValue("api+tooling"),
  UtmContent: literalFieldValue("landing"),
}
  
// metadata can be any custom map
metadata := map[string]interface{}{
  "email": "john@acmeinc.com",
  "first_name": "John",
  "last_name": "Doe",
  "title": "Software Engineer",
  "sales_info": map[string]interface{}{
      "stage": "Customer",
      "lifetime_value": 24000,
      "account_owner": "mary@contoso.com",
  },
}

// Only UserId is required
userA := models.UserModel{
  UserId:    "12345",
  CompanyId: literalFieldValue("67890"), // If set, associate user with a company object
  Campaign:  &campaign,
  Metadata:  &metadata,
}

users = append(users, &userA)

// Update Users
moesifgin.UpdateUsersBatch(users, moesifOptions)

The metadata field can contain any user demographic or other information you want to store.

Only the UserId field is required. This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation

Update Company

UpdateCompany Method

Use this method to create or update a company profile in Moesif.

import (
    "github.com/moesif/moesifgin"
    "github.com/moesif/moesifapi-go/models"
)

func literalFieldValue(value string) *string {
    return &value
}

moesifOptions := map[string]interface{} {
    "Application_Id": "YOUR_MOESIF_APPLICATION_ID",
}

// Campaign object is optional, but useful if you want to track ROI of acquisition channels
// See https://www.moesif.com/docs/api#update-a-company for campaign schema
campaign := models.CampaignModel {
  UtmSource: literalFieldValue("google"),
  UtmMedium: literalFieldValue("cpc"), 
  UtmCampaign: literalFieldValue("adwords"),
  UtmTerm: literalFieldValue("api+tooling"),
  UtmContent: literalFieldValue("landing"),
}
  
// metadata can be any custom map
metadata := map[string]interface{}{
  "org_name": "Acme, Inc",
  "plan_name": "Free",
  "deal_stage": "Lead",
  "mrr": 24000,
  "demographics": map[string]interface{}{
      "alexa_ranking": 500000,
      "employee_count": 47,
  },
}

// Prepare company model
company := models.CompanyModel{
    CompanyId:     "67890",    // The only required field is your company id
    CompanyDomain: literalFieldValue("acmeinc.com"), // If domain is set, Moesif will enrich your profiles with publicly available info 
    Campaign:      &campaign,
    Metadata:      &metadata,
}

// Update Company
moesifgin.UpdateCompany(&company, moesifOptions)

The metadata field can be any company demographic or other info you want to store.

Only the CompanyId field is required.

This method is a convenient helper that calls the Moesif API library. For details, see Moesif Go API documentation.

UpdateCompaniesBatch Method

Similar to UpdateCompany, but to update a list of companies in one batch.

import (
    "github.com/moesif/moesifgin"
    "github.com/moesif/moesifapi-go/models"
)

func literalFieldValue(value string) *string {
    return &value
}

moesifOptions := map[string]interface{} {
    "Application_Id": "YOUR_MOESIF_APPLICATION_ID",
}

// List of Companies
var companies []*models.CompanyModel

// Campaign object is optional, but useful if you want to track ROI of acquisition channels
// See https://www.moesif.com/docs/api#update-a-company for campaign schema
campaign := models.CampaignModel {
  UtmSource: literalFieldValue("google"),
  UtmMedium: literalFieldValue("cpc"), 
  UtmCampaign: literalFieldValue("adwords"),
  UtmTerm: literalFieldValue("api+tooling"),
  UtmContent: literalFieldValue("landing"),
}
  
// metadata can be any custom map
metadata := map[string]interface{}{
  "org_name": "Acme, Inc",
  "plan_name": "Free",
  "deal_stage": "Lead",
  "mrr": 24000,
  "demographics": map[string]interface{}{
      "alexa_ranking": 500000,
      "employee_count": 47,
  },
}

// Prepare company model
companyA := models.CompanyModel{
    CompanyId:     "67890",    // The only required field is your company id
    CompanyDomain: literalFieldValue("acmeinc.com"), // If domain is set, Moesif will enrich your profiles with publicly available info 
    Campaign:      &campaign,
    Metadata:      &metadata,
}

companies = append(companies, &companyA)

// Update Companies
moesifgin.UpdateCompaniesBatch(companies, moesifOptions)

The metadata field can be any company demographic or other info you want to store.

Only the CompanyId field is required.

This method is a convenient helper that calls the Moesif API library. For details, see Moesif Go API documentation.

Update Subscription

UpdateSubscription Method

Use this method to create or update a subscription profile in Moesif.

import (
    "github.com/moesif/moesifgin"
    "github.com/moesif/moesifapi-go/models"
)

func literalFieldValue(value string) *string {
    return &value
}

moesifOptions := map[string]interface{} {
    "Application_Id": "YOUR_MOESIF_APPLICATION_ID",
}

// metadata can be any custom map
metadata := map[string]interface{}{
  "plan_name": "Pro",
  "deal_stage": "Customer",
  "mrr": 48000,
  "demographics": map[string]interface{}{
      "subscription_length": 12,
      "subscription_type": "annual",
  },
}

// Prepare subscription model
subscription := models.SubscriptionModel{
    SubscriptionId: "12345",    // Required subscription id
    CompanyId:      "67890",    // Required company id
    Metadata:       &metadata,
}

// Update Subscription
moesifgin.UpdateSubscription(&subscription, moesifOptions)

The metadata field can be any subscription demographic or other information you want to store.

Only the SubscriptionId and CompanyId fields are required.

This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.

UpdateSubscriptionsBatch method

Similar to UpdateSubscription, but to update a list of subscriptions in one batch.

import (
    "github.com/moesif/moesifgin"
    "github.com/moesif/moesifapi-go/models"
)

func literalFieldValue(value string) *string {
    return &value
}

moesifOptions := map[string]interface{} {
    "Application_Id": "YOUR_MOESIF_APPLICATION_ID",
}

// List of Subscriptions
var subscriptions []*models.SubscriptionModel

// metadata can be any custom map
metadata := map[string]interface{}{
  "plan_name": "Pro",
  "deal_stage": "Customer",
  "mrr": 48000,
  "demographics": map[string]interface{}{
      "subscription_length": 12,
      "subscription_type": "annual",
  },
}

// Prepare subscription model
subscriptionA := models.SubscriptionModel{
    SubscriptionId: "12345",    // Required subscription id
    CompanyId:      "67890",    // Required company id
    Metadata:       &metadata,
}

subscriptions = append(subscriptions, &subscriptionA)

// Update Subscriptions
moesifgin.UpdateSubscriptionsBatch(subscriptions, moesifOptions)

The metadata field can be any subscription demographic or other information you want to store.

Only the SubscriptionId and CompanyId fields are required.

This method is a convenient helper that calls the Moesif API library. For more information, see Moesif Go API documentation.

Explore Other Integrations

Explore other integration options from Moesif:

Documentation

Overview

* moesifmiddleware-go

Index

Constants

This section is empty.

Variables

View Source
var ContextKeyRequestStart = &contextKey{"RequestStart"}
View Source
var DefaultTransport = &Transport{
	Transport: http.DefaultTransport,
}

The default logging transport that wraps http.DefaultTransport.

Functions

func HeaderToMap

func HeaderToMap(header http.Header) map[string]interface{}

func MoesifMiddleware

func MoesifMiddleware(configurationOption map[string]interface{}) gin.HandlerFunc

func NewLogGinResponseWriter

func NewLogGinResponseWriter(w gin.ResponseWriter) *logGinResponseWriter

func StartCaptureOutgoing

func StartCaptureOutgoing(configurationOption map[string]interface{})

Start Capture Outgoing Request

func UpdateCompaniesBatch

func UpdateCompaniesBatch(companies []*models.CompanyModel, configurationOption map[string]interface{})

Update Companies Batch

func UpdateCompany

func UpdateCompany(company *models.CompanyModel, configurationOption map[string]interface{})

Update Company

func UpdateSubscription

func UpdateSubscription(subscription *models.SubscriptionModel, configurationOption map[string]interface{})

Update Subscription

func UpdateSubscriptionsBatch

func UpdateSubscriptionsBatch(subscriptions []*models.SubscriptionModel, configurationOption map[string]interface{})

Update Subscriptions Batch

func UpdateUser

func UpdateUser(user *models.UserModel, configurationOption map[string]interface{})

Update User

func UpdateUsersBatch

func UpdateUsersBatch(users []*models.UserModel, configurationOption map[string]interface{})

Update Users Batch

Types

type AppConfig

type AppConfig struct {
	Mu      sync.RWMutex
	Updates chan string
	// contains filtered or unexported fields
}

func NewAppConfig

func NewAppConfig() AppConfig

func (*AppConfig) GetEntityValues

func (c *AppConfig) GetEntityValues(userId, companyId string) (userValues, companyValues []EntityRuleValues)

func (*AppConfig) Go

func (c *AppConfig) Go()

func (*AppConfig) Notify

func (c *AppConfig) Notify(eTag string)

func (*AppConfig) Read

func (c *AppConfig) Read() AppConfigResponse

func (*AppConfig) UpdateLoop

func (c *AppConfig) UpdateLoop()

func (*AppConfig) Write

func (c *AppConfig) Write(config AppConfigResponse)

type AppConfigResponse

type AppConfigResponse struct {
	OrgID                    string                        `json:"org_id"`
	AppID                    string                        `json:"app_id"`
	SampleRate               int                           `json:"sample_rate"`
	BlockBotTraffic          bool                          `json:"block_bot_traffic"`
	UserSampleRate           map[string]int                `json:"user_sample_rate"`    // user id to a sample rate [0, 100]
	CompanySampleRate        map[string]int                `json:"company_sample_rate"` // company id to a sample rate [0, 100]
	UserRules                map[string][]EntityRuleValues `json:"user_rules"`          // user id to a rule id and template values
	CompanyRules             map[string][]EntityRuleValues `json:"company_rules"`       // company id to a rule id and template values
	IPAddressesBlockedByName map[string]string             `json:"ip_addresses_blocked_by_name"`
	RegexConfig              []RegexRule                   `json:"regex_config"`
	BillingConfigJsons       map[string]string             `json:"billing_config_jsons"`
	// contains filtered or unexported fields
}

func NewAppConfigResponse

func NewAppConfigResponse() AppConfigResponse

type EntityRuleValues

type EntityRuleValues struct {
	Rule   string            `json:"rules"`
	Values map[string]string `json:"values"`
}

EntityRule is a user rule or company rule

type RegexCondition

type RegexCondition struct {
	Path  string `json:"path"`
	Value string `json:"value"`
}

RegexCondition

type RegexRule

type RegexRule struct {
	Conditions []RegexCondition `json:"conditions"`
	SampleRate int              `json:"sample_rate"`
}

Regex Rule

type Transport

type Transport struct {
	Transport   http.RoundTripper
	LogRequest  func(req *http.Request)
	LogResponse func(resp *http.Response)
}

Transport implements http.RoundTripper.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(request *http.Request) (*http.Response, error)

RoundTrip is the core part of this module and implements http.RoundTripper.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL