Skip to content
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

Go Agent 3.20.0. Release #596

Merged
merged 30 commits into from Nov 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ae5e140
Fix typos in log_event.go
gqgs Sep 22, 2022
8f0fce7
Merge pull request #582 from gqgs/patch-1
iamemilio Sep 23, 2022
257c712
initial working cut at module dependency metrics
nr-swilloughby Sep 29, 2022
84f3ed9
changed format of MDM reported modules
nr-swilloughby Oct 19, 2022
97ceea0
changed to enable MDM by default
nr-swilloughby Oct 19, 2022
0948bdd
updated unit tests
nr-swilloughby Oct 19, 2022
0899e12
added unit tests
nr-swilloughby Oct 19, 2022
3374c44
removed indirect deps in go.mod
nr-swilloughby Oct 19, 2022
f5ec4f3
removed yoda conditionals
nr-swilloughby Oct 19, 2022
48367f1
added config options for redaction and made redaction on by default
nr-swilloughby Oct 20, 2022
97f918e
consistent pluralization of options for CLM
nr-swilloughby Oct 20, 2022
3ddc5ee
Adjusted call signature for MDM IgnoredPrefixes option to be consiste…
nr-swilloughby Oct 20, 2022
ef4754a
fixed typos
nr-swilloughby Oct 21, 2022
cfd22f8
Release 3.20.0 Notes (#593)
nr-swilloughby Nov 2, 2022
08c5d0c
Merge pull request #591 from nr-swilloughby/pluralize_consistently
iamemilio Nov 2, 2022
a948158
Merge branch 'develop' into mdm
iamemilio Nov 2, 2022
539f804
Merge pull request #590 from newrelic/mdm
iamemilio Nov 2, 2022
4e5fe13
enable application logging by default
iamemilio Oct 17, 2022
af16e1f
updated naming for logging env vars to standardize with other agents
iamemilio Oct 18, 2022
f715662
Merge pull request #589 from iamemilio/logging-on-by-default
iamemilio Nov 2, 2022
2168b44
More Defensive zerologWriter parsing (#584)
iamemilio Nov 2, 2022
42f1ec2
Added Integration Tests to Harvest Cycle
mirackara Aug 15, 2022
8d611c2
Fixed typo in test
mirackara Aug 15, 2022
8ed6e5d
Linter fixes
mirackara Aug 15, 2022
70d6532
Linter Fix
mirackara Aug 15, 2022
9991a3e
Removed broken v2 integration test
mirackara Aug 15, 2022
bb76c82
Custom Events Harvest Limit Increase
mirackara Aug 16, 2022
9a02b17
add config option to toggle customEvents
iamemilio Oct 21, 2022
02f034f
Merge pull request #553 from mirackara/CustomEventsHarvestIncrease
iamemilio Nov 2, 2022
d947486
Integration Tests for Custom Events Limit Updates (#552)
mirackara Nov 2, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/ci.yaml
Expand Up @@ -51,8 +51,6 @@ jobs:
- go-version: 1.13.x
dirs: _integrations/nrecho
pin: github.com/labstack/echo@v3.3.10
- go-version: 1.13.x
dirs: _integrations/nrgin/v1
- go-version: 1.13.x
dirs: _integrations/nrgorilla/v1
- go-version: 1.13.x
Expand Down
42 changes: 42 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,45 @@
## 3.20.0

**PLEASE READ** these changes, and verify your config settings to ensure your application behaves how you intend it to. This release changes some default behaviors in the go agent.

### Added
* The Module Dependency Metrics feature was added. This collects the list of modules imported into your application, to aid in management of your application dependencies, enabling easier vulnerability detection and response, etc.
* This feature is enabled by default, but may be disabled by explicitly including `ConfigModuleDependencyMetricsEnable(false)` in your application, or setting the equivalent environment variable or `Config` field direclty.
* Modules may be explicitly excluded from the report via the `ConfigModuleDependencyMetricsIgnoredPrefixes` option.
* Excluded module names may be redacted via the `ConfigModuleDependencyMetricsRedactIgnoredPrefixes` option. This is enabled by default.
* Application Log Forwarding will now be **ENABLED** by default
* Automatic application log forwarding is now enabled by default. This means that logging frameworks wrapped with one of the [logcontext-v2 integrations](https://docs.newrelic.com/docs/apm/agents/go-agent/get-started/go-agent-compatibility-requirements/) will automatically send enriched application logs to New Relic with this version of the agent. To learn more about this feature, see the [APM logs in context documentation](https://docs.newrelic.com/docs/logs/logs-context/logs-in-context/). For additional configuration options, see the [Go logs in context documentation](https://docs.newrelic.com/docs/logs/logs-context/configure-logs-context-go). To learn about how to toggle log ingestion on or off by account, see our documentation to [disable automatic](https://docs.newrelic.com/docs/logs/logs-context/disable-automatic-logging) logging via the UI or API.
* If you are using a logcontext-v2 extension, but don't want the agent to automatically forward logs, please configure `ConfigAppLogForwardingEnabled(false)` in your application.
* Environment variables have been added for all application logging config options:
* `NEW_RELIC_APPLICATION_LOGGING_ENABLED`
* `NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED`
* `NEW_RELIC_APPLICATION_LOGGING_FORWARDING_MAX_SAMPLES_STORED`
* `NEW_RELIC_APPLICATION_LOGGING_METRICS_ENABLED`
* `NEW_RELIC_APPLICATION_LOGGING_LOCAL_DECORATING_ENABLED`
* Custom Event Limit Increase
* This version increases the **DEFAULT** limit of custom events from 10,000 events per minute to 30,000 events per minute. In the scenario that custom events were being limited, this change will allow more custom events to be sent to New Relic. There is also a new configurable **MAXIMUM** limit of 100,000 events per minute. To change the limits, set `ConfigCustomInsightsEventsMaxSamplesStored(limit)` to the limit you want in your application. To learn more about the change and how to determine if custom events are being dropped, see our Explorers Hub [post](https://discuss.newrelic.com/t/send-more-custom-events-with-the-latest-apm-agents/190497).
* New config option `ConfigCustomInsightsEventsEnabled(false)` can be used to disable the collection of custom events in your application.

### Changed
* Changed the following names to be consistent with their usage and other related identifier names. The old names remain for backward compatibility, but new code should use the new names.
* `ConfigCodeLevelMetricsIgnoredPrefix` -> `ConfigCodeLevelMetricsIgnoredPrefixes`
* `ConfigCodeLevelMetricsPathPrefix` -> `ConfigCodeLevelMetricsPathPrefixes`
* `NEW_RELIC_CODE_LEVEL_METRICS_PATH_PREFIX` -> `NEW_RELIC_CODE_LEVEL_METRICS_PATH_PREFIXES`
* `NEW_RELIC_CODE_LEVEL_METRICS_IGNORED_PREFIX` -> `NEW_RELIC_CODE_LEVEL_METRICS_IGNORED_PREFIXES`

* When excluding information reported from CodeLevelMetrics via the `IgnoredPrefixes` or `PathPrefixes` configuration fields (e.g., by specifying `ConfigCodeLevelMetricsIgnoredPrefixes` or `ConfigCodeLevelMetricsPathPrefixes`), the names of the ignored prefixes and the configured path prefixes may now be redacted from the agent configuration information sent to New Relic.
* This redaction is enabled by default, but may be disabled by supplying a `false` value to `ConfigCodeLevelMetricsRedactPathPrefixes` or `ConfigCodeLevelMetricsRedactIgnoredPrefixes`, or by setting the corresponding `Config` fields or environment variables to `false`.

### Fixed
* [#583](https://github.com/newrelic/go-agent/issues/583): fixed a bug in zerologWriter where comma separated fields in log message confused the JSON parser and could cause panics.

### Support Statement
New Relic recommends that you upgrade the agent regularly to ensure that you’re getting the latest features and performance benefits. Additionally, older releases will no longer be supported when they reach end-of-life.

We also recommend using the latest version of the Go language. At minimum, you should at least be using no version of Go older than what is supported by the Go team themselves.

See the [Go Agent EOL Policy](https://docs.newrelic.com/docs/apm/agents/go-agent/get-started/go-agent-eol-policy/) for details about supported versions of the Go Agent and third-party components.

## 3.19.2

### Changed
Expand Down
122 changes: 92 additions & 30 deletions v3/integrations/logcontext-v2/zerologWriter/zerolog-writer.go
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"io"
"strings"
"time"
"unicode"

"github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter"
"github.com/newrelic/go-agent/v3/internal"
Expand Down Expand Up @@ -51,22 +53,33 @@ func parseJSONLogData(log []byte) newrelic.LogData {
// For this iteration of the tool, the entire log gets captured as the message
data := newrelic.LogData{}
data.Message = string(log)
data.Timestamp = time.Now().UnixMilli()

for i := 0; i < len(log)-1; {
// get key; always a string field
key, keyEnd := getStringField(log, i)

// find index where value starts
valStart := getValueIndex(log, keyEnd)
valEnd := valStart
key, valStart := getKey(log, i)
var next int

// NOTE: depending on the key, the type of field the value is can differ
switch key {
case zerolog.LevelFieldName:
data.Severity, valEnd = getStringField(log, valStart)
data.Severity, next = getStringValue(log, valStart+1)
case zerolog.ErrorStackFieldName:
_, next = getStackTrace(log, valStart)
default:
if i >= len(log)-1 {
return data
}
// TODO: once we update the logging spec to support custom attributes, capture these
if isStringValue(log, valStart) {
_, next = getStringValue(log, valStart+1)
} else if isNumberValue(log, valStart) {
_, next = getNumberValue(log, valStart)
} else {
return data
}
}

next := nextKeyIndex(log, valEnd)
if next == -1 {
return data
}
Expand All @@ -76,49 +89,98 @@ func parseJSONLogData(log []byte) newrelic.LogData {
return data
}

func getValueIndex(p []byte, indx int) int {
// Find the index where the value begins
for i := indx; i < len(p)-1; i++ {
if p[i] == ':' {
return i + 1
}
}

return -1
func isStringValue(p []byte, indx int) bool {
return p[indx] == '"'
}

func nextKeyIndex(p []byte, indx int) int {
// Find the index where the key begins
for i := indx; i < len(p)-1; i++ {
if p[i] == ',' {
return i + 1
}
}

return -1
func isNumberValue(p []byte, indx int) bool {
return unicode.IsDigit(rune(p[indx]))
}

func getStringField(p []byte, indx int) (string, int) {
// zerolog keys are always JSON strings
func getKey(p []byte, indx int) (string, int) {
value := strings.Builder{}
i := indx

// find start of string field
for ; i < len(p)-1; i++ {
for ; i < len(p); i++ {
if p[i] == '"' {
i += 1
break
}
}

// parse value of string field
for ; i < len(p)-1; i++ {
if p[i] == '"' {
return value.String(), i + 1
for ; i < len(p); i++ {
if p[i] == '"' && i+1 < len(p) && p[i+1] == ':' {
return value.String(), i + 2
} else {
value.WriteByte(p[i])
}
}

return "", -1
}

func isEOL(p []byte, i int) bool {
return p[i] == '}' && i+2 == len(p)
}

func getStringValue(p []byte, indx int) (string, int) {
value := strings.Builder{}

// parse value of string field
for i := indx; i < len(p); i++ {
if p[i] == '"' && i+1 < len(p) {
if p[i+1] == ',' && i+2 < len(p) && p[i+2] == '"' {
return value.String(), i + 2
} else if isEOL(p, i+1) {
return value.String(), -1
}
}
value.WriteByte(p[i])
}

return "", -1
}

func getNumberValue(p []byte, indx int) (string, int) {
value := strings.Builder{}

// parse value of string field
for i := indx; i < len(p); i++ {
if p[i] == ',' && i+1 < len(p) && p[i+1] == '"' {
return value.String(), i + 1
} else if isEOL(p, i) {
return value.String(), -1
} else {
value.WriteByte(p[i])
}
}

return "", -1
}

func getStackTrace(p []byte, indx int) (string, int) {
value := strings.Builder{}

// parse value of string field
for i := indx; i < len(p); i++ {
if p[i] == ']' {
value.WriteByte(p[i])

if i+1 < len(p) {
if isEOL(p, i+1) {
return value.String(), -1
}
if p[i+1] == ',' && i+2 < len(p) && p[i+2] == '"' {
return value.String(), i + 2
}
}
} else {
value.WriteByte(p[i])
}
}

return value.String(), -1
}