Skip to content

Commit

Permalink
implemented String() methods for internalStats (#133)
Browse files Browse the repository at this point in the history
* implemented String() methods for internalStats

* rename type

* cleanup
  • Loading branch information
cristianciutea authored Aug 31, 2022
1 parent 0b9ce66 commit 56d0060
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 26 deletions.
4 changes: 2 additions & 2 deletions gojmx/gojmx.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,13 @@ func (c *Client) QueryMBeanAttributes(mBeanNamePattern string, mBeanAttrName ...
// Internal statistics must be enabled using JMXConfig.EnableInternalStats flag.
// Additionally you can set a maximum size for the collected stats using JMXConfig.MaxInternalStatsSize. (default: 100000)
// Each time you retrieve GetInternalStats, the internal stats will be cleaned.
func (c *Client) GetInternalStats() ([]*InternalStat, error) {
func (c *Client) GetInternalStats() (InternalStatsList, error) {
if err := c.checkNRJMXProccessError(); err != nil {
return nil, err
}
result, err := c.jmxService.GetInternalStats(c.ctx)

return toInternalStatList(result), c.handleError(err)
return toInternalStatsList(result), c.handleError(err)
}

// connect will pass the JMXConfig to nrjmx subprocess and establish the
Expand Down
59 changes: 36 additions & 23 deletions gojmx/gojmx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -905,33 +905,46 @@ func TestGetInternalStats(t *testing.T) {
internalStats, err := client.GetInternalStats()
assert.NoError(t, err)

totalCalls := 0
totalObjects := 0
totalTimeMs := 0
totalAttrs := 0
totalSucessful := 0

for _, stat := range internalStats {
totalCalls++
totalObjects += int(stat.ResponseCount)
totalTimeMs += int(stat.Milliseconds)
totalAttrs += len(stat.Attrs)

if stat.Successful {
totalSucessful++
}
}

assert.Equal(t, 3000, totalCalls)
assert.Equal(t, 18000, totalObjects)
assert.True(t, totalTimeMs > 0)
assert.Equal(t, 9000, totalAttrs)
assert.Equal(t, 3000, totalSucessful)
assert.Len(t, internalStats, 3000)
assert.Regexp(t, "StatType: 'getMBeanInfo', MBean: 'test:type=Cat,name=(.+?)', Attributes: '[]', TotalObjCount: 6, StartTimeMs: [0-9]+, Duration: [0-9]+\\.[0-9]+ms, Successful: true", internalStats[0].String())
assert.Regexp(t, "TotalMs: '[0-9]+\\.[0-9]{3}', TotalObjects: 18000, TotalAttr: 9000, TotalCalls: 3000, TotalSuccessful: 3000", internalStats.String())

// AND internal stats get cleaned
internalStats, err = client.GetInternalStats()
assert.NoError(t, err)
assert.True(t, len(internalStats) == 0)
assert.Equal(t, "TotalMs: '0.000', TotalObjects: 0, TotalAttr: 0, TotalCalls: 0, TotalSuccessful: 0", internalStats.String())
}

func TestGetEmptyInternalStats(t *testing.T) {
ctx := context.Background()

// GIVEN a JMX Server running inside a container
container, err := testutils.RunJMXServiceContainer(ctx)
require.NoError(t, err)
defer container.Terminate(ctx)

jmxHost, jmxPort, err := testutils.GetContainerMappedPort(ctx, container, testutils.TestServerJMXPort)
require.NoError(t, err)

// THEN JMX connection can be oppened
config := &JMXConfig{
Hostname: jmxHost,
Port: int32(jmxPort.Int()),
EnableInternalStats: false,
}

client, err := NewClient(ctx).Open(config)
assert.NoError(t, err)
defer assertCloseClientNoError(t, client)

_, err = client.QueryMBeanAttributes("test:type=Cat,*")
assert.NoError(t, err)

// AND query doesn't generate any internal stats.
internalStats, err := client.GetInternalStats()

assert.Error(t, err)
assert.Equal(t, "<nil>", internalStats.String())
}

func TestConnectionRecovers(t *testing.T) {
Expand Down
32 changes: 31 additions & 1 deletion gojmx/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,40 @@ func (is *InternalStat) String() string {
)
}

func toInternalStatList(in []*nrprotocol.InternalStat) []*InternalStat {
func toInternalStatsList(in []*nrprotocol.InternalStat) InternalStatsList {
return *(*[]*InternalStat)(unsafe.Pointer(&in))
}

type InternalStatsList []*InternalStat

func (is InternalStatsList) String() string {
if is == nil {
return "<nil>"
}

var totalCalls = len(is)
var totalObjects, totalAttrs, totalSuccessful int

var totalTimeMs float64

for _, stat := range is {
if stat.Successful {
totalSuccessful++
}

totalObjects += int(stat.ResponseCount)
totalTimeMs += stat.Milliseconds
totalAttrs += len(stat.Attrs)
}
return fmt.Sprintf("TotalMs: '%.3f', TotalObjects: %d, TotalAttr: %d, TotalCalls: %d, TotalSuccessful: %d",
totalTimeMs,
totalObjects,
totalAttrs,
totalCalls,
totalSuccessful,
)
}

// JMXClientError is returned when there is an nrjmx process error.
// Those errors require opening a new client.
type JMXClientError struct {
Expand Down

0 comments on commit 56d0060

Please sign in to comment.