gometricsnewrelicbeego

Problems with Beego and Newrelic integration


I'm in the process of creating a web application in Go using Beego (https://beego.me).

I have a requirement to capture application monitoring and metering metrics in Newrelic and to be able to view all transactions in Newrelic.

I have followed this documentation and am using Beego GoRelic to initialise the Newrelic agent in my code.

Here is my router.go class -

import (
    "github.com/astaxie/beego"
    "github.com/yvasiyarov/beego_gorelic"
)

func init() {
    beego_gorelic.InitNewrelicAgent()
    beego.Router("path", &controller{}, "functionName") // code broken intentionally
}

In my app.conf, I have provided the newrelic licence key and the app name, like so :

NewrelicLicense = "key"
newrelicAppname = "App Name"

When I run the application in dev mode, Im able to see the metrics being printed, like so :

Send data:{
    "agent": {
        "host": "localhost",
        "version": "0.0.6",
        "pid": 13942
    },
    "components": [
        {
            "name": "Name",
            "guid": "com.github.yvasiyarov.GoRelic",
            "duration": 60,
            "metrics": {
                "Component/Runtime/GC/GCTime/Max[nanoseconds]": 0,
                "Component/Runtime/GC/GCTime/Mean[nanoseconds]": 0,
                "Component/Runtime/GC/GCTime/Min[nanoseconds]": 0,
                "Component/Runtime/GC/GCTime/Percentile95[nanoseconds]": 0,
                "Component/Runtime/GC/NumberOfGCCalls[calls]": 0,
                "Component/Runtime/GC/PauseTotalTime[nanoseconds]": 0,
                "Component/Runtime/General/NOCgoCalls[calls]": 1,
                "Component/Runtime/General/NOGoroutines[goroutines]": 6,
                "Component/Runtime/Memory/InUse/Heap[bytes]": 538368,
                "Component/Runtime/Memory/InUse/MCacheInuse[bytes]": 13888,
                "Component/Runtime/Memory/InUse/MSpanInuse[bytes]": 13192,
                "Component/Runtime/Memory/InUse/Stack[bytes]": 360448,
                "Component/Runtime/Memory/InUse/Total[bytes]": 538368,
                "Component/Runtime/Memory/Operations/NoFrees[frees]": 128,
                "Component/Runtime/Memory/Operations/NoMallocs[mallocs]": 2903,
                "Component/Runtime/Memory/Operations/NoPointerLookups[lookups]": 0,
                "Component/Runtime/Memory/SysMem/BuckHash[bytes]": 3078,
                "Component/Runtime/Memory/SysMem/Heap[bytes]": 66748416,
                "Component/Runtime/Memory/SysMem/MCache[bytes]": 16384,
                "Component/Runtime/Memory/SysMem/MSpan[bytes]": 16384,
                "Component/Runtime/Memory/SysMem/Stack[bytes]": 360448,
                "Component/Runtime/Memory/SysMem/Total[bytes]": 69928960,
                "Component/http/responseTime/max[ms]": 0,
                "Component/http/responseTime/mean[ms]": 0,
                "Component/http/responseTime/min[ms]": 0,
                "Component/http/responseTime/percentile75[ms]": 0,
                "Component/http/responseTime/percentile90[ms]": 0,
                "Component/http/responseTime/percentile95[ms]": 0,
                "Component/http/throughput/1minute[rps]": 0,
                "Component/http/throughput/rateMean[rps]": 0
            }
        }
    ],
    "URL": "https://platform-api.newrelic.com/platform/v1/metrics"
} 

This tells me that the new relic agent is started and is capturing the data.

I have not written any other code to integrate Newrelic in my code apart from this.

The metrics are not being reported to Newrelic with these settings and setup and Im not able to find better documentation to solve this.

What am I missing ?

Also, is there another way to integrate newrelic into a Beego application ?

P.S. I am not using Beego Filters as pre-processors but am using the prepare method in the controllers to pre-process the requests. However, this library seems to be adding 2 filters in the Beego framework, like so :

    beego.InsertFilter("*", beego.BeforeRouter, InitNewRelicTimer, false)
    beego.InsertFilter("*", beego.FinishRouter, ReportMetricsToNewrelic, false)

Additional Logs :

2020/01/09 20:13:29 Init GC metrics collection. Poll interval 10 seconds.
2020/01/09 20:13:29 Init memory allocator metrics collection. Poll interval 60 seconds.
2020/01/09 20:13:29 Init HTTP metrics collection.
2020/01/09 20:13:29 [I] [gorelic.go:71] NewRelic agent started 
2020/01/09 20:13:29 Can not get metrica: Runtime/System/Threads, got error:this metrica was not implemented yet for darwin
2020/01/09 20:13:29 Can not get metrica: Runtime/System/FDSize, got error:this metrica was not implemented yet for darwin
2020/01/09 20:13:29 Can not get metrica: Runtime/System/Memory/VmPeakSize, got error:this metrica was not implemented yet for darwin
2020/01/09 20:13:29 Can not get metrica: Runtime/System/Memory/VmCurrent, got error:this metrica was not implemented yet for darwin
2020/01/09 20:13:29 Can not get metrica: Runtime/System/Memory/RssPeak, got error:this metrica was not implemented yet for darwin
2020/01/09 20:13:29 Can not get metrica: Runtime/System/Memory/RssCurrent, got error:this metrica was not implemented yet for darwin
2020/01/09 20:13:29 Send data:{
    "agent": {
        "host": "localhost",
        "version": "0.0.6",
        "pid": 14931
    },
    "components": [
        {
            "name": "App Name",
            "guid": "com.github.yvasiyarov.GoRelic",
            "duration": 60,
            "metrics": {
                "Component/Runtime/GC/GCTime/Max[nanoseconds]": 0,
                "Component/Runtime/GC/GCTime/Mean[nanoseconds]": 0,
                "Component/Runtime/GC/GCTime/Min[nanoseconds]": 0,
                "Component/Runtime/GC/GCTime/Percentile95[nanoseconds]": 0,
                "Component/Runtime/GC/NumberOfGCCalls[calls]": 0,
                "Component/Runtime/GC/PauseTotalTime[nanoseconds]": 0,
                "Component/Runtime/General/NOCgoCalls[calls]": 1,
                "Component/Runtime/General/NOGoroutines[goroutines]": 8,
                "Component/Runtime/Memory/InUse/Heap[bytes]": 591616,
                "Component/Runtime/Memory/InUse/MCacheInuse[bytes]": 13888,
                "Component/Runtime/Memory/InUse/MSpanInuse[bytes]": 16592,
                "Component/Runtime/Memory/InUse/Stack[bytes]": 393216,
                "Component/Runtime/Memory/InUse/Total[bytes]": 591616,
                "Component/Runtime/Memory/Operations/NoFrees[frees]": 132,
                "Component/Runtime/Memory/Operations/NoMallocs[mallocs]": 2988,
                "Component/Runtime/Memory/Operations/NoPointerLookups[lookups]": 0,
                "Component/Runtime/Memory/SysMem/BuckHash[bytes]": 3078,
                "Component/Runtime/Memory/SysMem/Heap[bytes]": 66715648,
                "Component/Runtime/Memory/SysMem/MCache[bytes]": 16384,
                "Component/Runtime/Memory/SysMem/MSpan[bytes]": 32768,
                "Component/Runtime/Memory/SysMem/Stack[bytes]": 393216,
                "Component/Runtime/Memory/SysMem/Total[bytes]": 69928960,
                "Component/http/responseTime/max[ms]": 0,
                "Component/http/responseTime/mean[ms]": 0,
                "Component/http/responseTime/min[ms]": 0,
                "Component/http/responseTime/percentile75[ms]": 0,
                "Component/http/responseTime/percentile90[ms]": 0,
                "Component/http/responseTime/percentile95[ms]": 0,
                "Component/http/throughput/1minute[rps]": 0,
                "Component/http/throughput/rateMean[rps]": 0
            }
        }
    ],
    "URL": "https://platform-api.newrelic.com/platform/v1/metrics"
} 

Could this be the problem ? How can I solve this ?


Solution

  • Im answering my own question as I believe Ive found a way and it might help someone else too - apparently it was just a matter of looking harder for existing plugins. I found that this plugin : https://github.com/sergeylanzman/newrelic_beego does exactly what I needed.

    If we observe the code, it the author has created 3 methods -

    1. StartTransaction
    2. NameTransaction
    3. EndTransaction

    and is inserting these as filters in the Beego environment. Under the hood the author has used the official Newrelic Go Agent (https://github.com/newrelic/go-agent) and is using Transactions to report APM data.

    Here is the sample code from the plugin which registers the 3 filters -

        beego.InsertFilter("*", beego.BeforeRouter, StartTransaction, false)
        beego.InsertFilter("*", beego.AfterExec, NameTransaction, false)
        beego.InsertFilter("*", beego.FinishRouter, EndTransaction, false)
        beego.Info("NewRelic agent start")
    

    It uses Beego's Context struct to keep track of the transaction data across functions (as prescribed in the Context documentation)

    I'll be continuing to explore more on this and add tracking for external calls, DB calls and distributed tracing as and when we progress, but this solved my issue.

    P.S. I've stopped using the plugin which i was using earlier as this package also reports the Go Runtime stats to NewRelic, making the other plugin obsolete (Personal Opinion :) )