Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
gmann42 committed Apr 19, 2023
2 parents 145c376 + b693b02 commit bbba6b5
Show file tree
Hide file tree
Showing 16 changed files with 502 additions and 144 deletions.
44 changes: 44 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
## Naming conventions
<br>

### PR Title
PR Title should start with the JIRA ticket Id in square brackets, example: [AOB-100] with a human readable title to accompany it.

<br>

### Branch Names
Branch names should start with an action followed by a concise name of the action to be performed.

E.g.
- feature/add-hostname-support
- bug/incorrect-user-handling
- hotfix/no-userid-support

<br>

### Commit message
Commit messages should be descriptive and highlight the action performed. They should also start with the type of action performed, such as feat and fix. This leads to better
documentation when creating Github Releases.

Examples:
- feat: Use distribution bot app to upload tags
- fix: Stop spans from exporting when suppressed

They should NOT be terse and context-less.

Such as:
- fixed linting issue.
- format fix.

<br>

## Release Process
- Merge all the changes in `develop`.
- Create a new branch from `develop`, update the `version.go` file with the updated version. Raise a PR, get it reviwed and merged to `develop`.
- At this point, we have all the changes in `develop` which we want to tag and create a release for. Create a PR from `develop` to `master`.
- Fast-forward merge the PR into `master` [**Do not merge via the UI**]. This will trigger the `Release Go SDK` action, which will create the tag and Github release for the same.
```shell
# On master branch
git merge --ff develop
```
- Check the progress in Actions tab, and find the newly created release under Releases tag.
147 changes: 92 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,82 @@

This SDK instruments web frameworks to capture http requests and auto-generates Postman Live Collections.


## Installation Process

```
go get github.com/postmanlabs/postman-go-sdk
```


## Initializing the SDK

```golang
import (
pm "github.com/postmanlabs/postman-go-sdk/postmansdk"
)

func main() {
router := gin.Default()
sdk, err := pm.Initialize("<POSTMAN-COLLECTION-ID>", "<POSTMAN-API-KEY>")

if err == nil {
// Registers a custom middleware
sdk.Integrations.Gin(router)
}
}

```
```

For full working example see: [Gin instrumented example](https://github.com/postmanlabs/postman-go-sdk/tree/master/postmansdk/example/testgo)

## Configuration

**For initialization the SDK, the following values can be configured -**
#### Required Params

- **CollectionId**: Postman collectionId where requests will be added. This is the id for your live collection.

- Type: `string`

- **ApiKey**: Postman api key needed for authentication.

- Type: `string`

#### Configuration example

```golang
import (
pm "github.com/postmanlabs/postman-go-sdk/postmansdk"
)

sdk, err := pm.Initialize(
"<POSTMAN-COLLECTION-ID>",
"<POSTMAN-API-KEY>",
pm.WithDebug(false),
pm.WithEnable(true),
// ...Other configuration options
)

```

#### Configuration Options

- **WithDebug**: Enable/Disable debug logs.

- Type: `func(bool)`
- Default: `false`

- **collection_id**: Postman collectionId where requests will be added. This is the id for your live collection.
- Type: ```string```
- **WithEnable**: Enable/Disable the SDK.

- **api_key**: Postman api key needed for authentication.
- Type: ```string```
- Disabled SDK does not capture any new traces, nor does it use up system resources.
- Type: `func(bool)`
- Default: `true`

- **debug**: Enable/Disable debug logs.
- Type: ```boolean```
- Default: ```False```
- **WithTruncateData**: Truncate the request and response body so that no PII data is sent to Postman.

- **enable**: Enable/Disable the SDK. Disabled SDK does not capture any new traces, nor does it use up system resources.
- Type: ```boolean```
- Default: ```True```
- Disabling it sends actual request and response payloads.
- Type: `func(bool)`
- Default: `true`
- Example:

- **truncate_data**: Truncate the request and response body so that no PII data is sent to Postman. This is **enabled** by default. Disabling it sends actual request and response payloads.
- Example:
> Sample payload or non-truncated payload:
```JSON
Expand All @@ -52,54 +92,51 @@ This SDK instruments web frameworks to capture http requests and auto-generates
```JSON
{
"first_name": {
"type": "str"
"type": "string"
},
"age": {
"type": "int"
"type": "float64"
}
}
```
- Type: ```boolean```
- Default: ```True```

- **redact_sensitive_data**: Redact sensitive data such as api_keys and auth tokens, before they leave the sdk. This is **enabled** by default. But **NO** rules are set.
- Example:
```
{
"redact_sensitive_data": {
"enable": True(default),
"rules": {
"<rule name>": "<regex to match the rule>", # such as -
"basic_auth": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b",
},
}
}
- **WithRedactSensitiveData**: Redact sensitive data such as api_keys and auth tokens, before they leave the sdk.

- **enabled** by default.
- Default regex rules applied are

```golang
"pmPostmanAPIKey": `PMAK-[a-f0-9]{24}-[a-f0-9]{34}`,
"pmPostmanAccessKey": `PMAT-[0-9a-z]{26}`,
"pmBasicAuth": `Basic [a-zA-Z0-9]{3,1000}(?:[^a-z0-9+({})!@#$%^&|*=]{0,2})`,
"pmBearerToken": `Bearer [a-z0-9A-Z-._~+/]{15,1000}`,
```
- Type: ```object```

- **ignore_incoming_requests**: List of regexes to be ignored from instrumentation. This rule only applies to endpoints that are **served** by the application/server.
- Example:
```python
{
"ignore_incoming_requests": ["knockknock", "^get.*"]
}
```
The above example, will ignore any endpoint that contains the word "knockknock" in it, and all endpoints that start with get, and contain any characters after that.
- Type: ```dict```

- **ignore_outgoing_requests**: List of regexes to be ignored from instrumentation. This rule only applies to endpoints that are **called** by the application/server.
- Example:
```python
{
"ignore_outgoing_requests": ["knockknock", "^get.*"]
}
```
The above example, will ignore any endpoint that contains the word "knockknock" in it, and all endpoints that start with get, and contain any characters after that.
- Type: ```dict```
```golang
WithRedactSensitiveData(
true,
map[string]string{
"<rule name>": "<regex to match the rule>",
"key": `PMAT-[0-9a-z]{26}`,
}
)
```
- Type: `func(bool, map[string][string])`

- **buffer_interval_in_milliseconds**: The interval in milliseconds that the SDK waits before sending data to Postman. The default interval is 5000 milliseconds. This interval can be tweaked for lower or higher throughput systems.
- Type: ```int```
- Default: ```5000```
- **WithIgnoreIncomingRequests**: List of regexes to be ignored from instrumentation.

- This rule only applies to endpoints that are **served** by the application/server.

- Example:
```golang
WithIgnoreIncomingRequests(
[]string{"knockknock", "^get.*"}
)
```
Ignore any incoming request endpoints matching the two regexes.
- Type: `func([]string)`

- **WithBufferIntervalInMilliseconds**: Interval between SDK data push to backend
- Type: `func(int)`
- Default: `5000` milliseconds
18 changes: 10 additions & 8 deletions postmansdk/example/testgo/main.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
package main

import (
"context"

"github.com/gin-gonic/gin"

pm "github.com/postmanlabs/postman-go-sdk/postmansdk"
pminterfaces "github.com/postmanlabs/postman-go-sdk/postmansdk/interfaces"
)

func main() {

apiKey := "REPLACE-THIS"
collectionId := "REPLACE-THIS"
Rules := map[string]string{
"amazonAccessKeyId": "AKIA[0-9A-Z]{16}",
}

router := gin.Default()
cleanup, err := pm.Initialize(collectionId, apiKey, pminterfaces.WithReceiverBaseUrl("REPLACE THIS"))

psdk, err := pm.Initialize(
collectionId,
apiKey,
pm.WithReceiverBaseUrl("REPLACE-THIS"),
pm.WithRedactSensitiveData(true, Rules),
)
if err == nil {
defer cleanup(context.Background())
pm.InstrumentGin(router)
psdk.Integrations.Gin(router)
}

router.GET("/albums", getAlbums)
Expand Down
28 changes: 25 additions & 3 deletions postmansdk/exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
tracesdk "go.opentelemetry.io/otel/sdk/trace"

plugins "github.com/postmanlabs/postman-go-sdk/postmansdk/exporter/plugins"
pminterfaces "github.com/postmanlabs/postman-go-sdk/postmansdk/interfaces"
pmutils "github.com/postmanlabs/postman-go-sdk/postmansdk/utils"
)
Expand All @@ -21,8 +22,29 @@ func (e *PostmanExporter) ExportSpans(ctx context.Context, ss []tracesdk.ReadOnl
}

pmutils.Log.Debug("Spans to be exported are")
for idx, span := range ss {
pmutils.Log.Debug("Span number:%d span:%+v", idx, span)

var processedSpans []tracesdk.ReadOnlySpan
for _, span := range ss {
if e.Sdkconfig.Options.TruncateData {
err := plugins.Truncate(span)
if err != nil {
pmutils.Log.WithError(err).Error("Failure in truncation.")
pmutils.Log.WithField("span", span).Debug("Skipping the span.")
continue
}
}

if e.Sdkconfig.Options.RedactSensitiveData.Enable {
err := plugins.Redact(span, e.Sdkconfig.Options.RedactSensitiveData.Rules)
if err != nil {
pmutils.Log.WithError(err).Error("Failure in redaction.")
pmutils.Log.WithField("span", span).Debug("Skipping the span.")
continue
}
}

processedSpans = append(processedSpans, span)
pmutils.Log.WithField("span attributes - ", span.Attributes()).Debug("Span - ")
}
return e.Exporter.ExportSpans(ctx, ss)
return e.Exporter.ExportSpans(ctx, processedSpans)
}
29 changes: 29 additions & 0 deletions postmansdk/exporter/plugins/plugin_constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package plugins

// Key: attribute name
// Value: should truncate or not
var attrNameTruncate = map[string]bool{
"http.request.body": true,
"http.response.body": true,
}

var defaultRedactionRules = map[string]string{
"pmPostmanAPIKey": `PMAK-[a-f0-9]{24}-[a-f0-9]{34}`,
"pmPostmanAccessKey": `PMAT-[0-9a-z]{26}`,
"pmBasicAuth": `Basic [a-zA-Z0-9]{3,1000}(?:[^a-z0-9+({})!@#$%^&|*=]{0,2})`,
"pmBearerToken": `Bearer [a-z0-9A-Z-._~+/]{15,1000}`,
}

// Key: attribute name
// Value: should redact or not
var attrNameRedact = map[string]bool{
"http.request.body": true,
"http.request.headers": true,
"http.url": true,
"http.request.query": true,
"http.target": true,
"http.response.body": true,
"http.response.headers": true,
}

const defaultRedactionReplacementString = "*****"
Loading

0 comments on commit bbba6b5

Please sign in to comment.