Skip to content

Commit 02ed2b2

Browse files
committed
Implement metrics
1 parent 7084aed commit 02ed2b2

File tree

3 files changed

+117
-3
lines changed

3 files changed

+117
-3
lines changed

ModuleConfig.cfc

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ component {
44
this.author = "Eric Peterson";
55
this.webUrl = "https://github.com/coldbox-modules/unleashsdk";
66
this.dependencies = [ "hyper" ];
7+
this.version = "0.1.0";
78

89
function configure() {
910
settings = {
11+
"appName": getApplicationName(),
12+
"instanceId": resolveHostname(),
1013
"environment": variables.controller.getSetting( "environment" ),
1114
"contextProvider": "DefaultContextProvider@unleashsdk",
1215
"apiURL": getSystemSetting( "UNLEASH_API_URL" ),
1316
"apiToken": getSystemSetting( "UNLEASH_API_TOKEN" ),
14-
"refreshInterval": 10
17+
"refreshInterval": 10,
18+
"metricsInterval": 60
1519
};
1620

1721
binder.map( "UnleashHyperClient@unleashsdk" )
@@ -34,7 +38,27 @@ component {
3438
}
3539

3640
function onLoad() {
37-
41+
wirebox.getInstance( "UnleashSDK@unleashsdk" ).register();
42+
}
43+
44+
private string function getApplicationName() {
45+
try {
46+
return getApplicationSettings().name;
47+
} catch ( any e ) {
48+
return "";
49+
}
50+
}
51+
52+
private string function resolveHostname() {
53+
var hostname = createObject( "java", "java.lang.System" ).getProperty( "hostname" );
54+
if ( isNull( hostname ) ) {
55+
try {
56+
hostname = createObject( "java", "java.net.InetAddress" ).getLocalHost().getHostName();
57+
} catch ( UnknownHostException e ) {
58+
hostname = "undefined";
59+
}
60+
}
61+
return hostname;
3862
}
3963

4064
}

config/Scheduler.cfc

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
component {
22

33
property name="refreshInterval" inject="coldbox:setting:refreshInterval@unleashsdk";
4+
property name="metricsInterval" inject="coldbox:setting:metricsInterval@unleashsdk";
45
property name="log" inject="logbox:logger:{this}";
56

67
function configure() {
@@ -9,7 +10,7 @@ component {
910
.every( variables.refreshInterval, "seconds" )
1011
.before( function() {
1112
if ( log.canDebug() ) {
12-
log.debug( "Starting to fetch new features from unleash" );
13+
log.debug( "Starting to fetch new features from Unleash" );
1314
}
1415
} )
1516
.onSuccess( function( task, results ) {
@@ -22,6 +23,26 @@ component {
2223
log.error( "Exception when running task [unleashsdk-refresh-features]:", exception );
2324
}
2425
} );
26+
27+
task( "unleashsdk-send-metrics" )
28+
.call( getInstance( "UnleashSDK@unleashsdk" ), "sendMetrics" )
29+
.every( variables.metricsInterval, "seconds" )
30+
.delay( variables.metricsInterval, "seconds" )
31+
.before( function() {
32+
if ( log.canDebug() ) {
33+
log.debug( "Starting to send metrics to Unleash" );
34+
}
35+
} )
36+
.onSuccess( function( task, results ) {
37+
if ( log.canInfo() ) {
38+
log.info( "Successfully sent metrics to Unleash features", results );
39+
}
40+
} )
41+
.onFailure( function( task, exception ) {
42+
if ( log.canError() ) {
43+
log.error( "Exception when running task [unleashsdk-send-metrics]:", exception );
44+
}
45+
} );
2546
}
2647

2748
}

models/UnleashSDK.cfc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
component singleton accessors="true" {
22

33
property name="settings" inject="coldbox:moduleSettings:unleashsdk";
4+
property name="config" inject="coldbox:moduleConfig:unleashsdk";
45
property name="client" inject="UnleashHyperClient@unleashsdk";
56
property name="log" inject="logbox:logger:{this}";
67
property name="cache" inject="cachebox:default";
@@ -14,10 +15,39 @@ component singleton accessors="true" {
1415
"applicationHostname" : "ApplicationHostnameStrategy@unleashsdk"
1516
};
1617

18+
function onDIComplete() {
19+
variables.metricsBucket = newMetricsBucket();
20+
}
21+
22+
function register() {
23+
var registrationInfo = {
24+
"appName" : variables.settings.appName,
25+
"instanceId" : variables.settings.instanceId,
26+
"sdkVersion" : "coldbox-modules/unleashsdk:#variables.config.version#",
27+
"strategies" : variables.strategies.keyArray(),
28+
"started" : getIsoTimeString( now() ),
29+
"interval" : variables.settings.metricsInterval * 1000
30+
};
31+
if ( log.canInfo() ) {
32+
log.info( "Registering instance with Unleash", registrationInfo );
33+
}
34+
variables.client.post( "/client/register", registrationInfo );
35+
}
36+
1737
public boolean function isEnabled(
1838
required string name,
1939
struct additionalContext = {},
2040
boolean defaultValue = false
41+
) {
42+
var enabled = checkEnabled( argumentCollection = arguments );
43+
countForMetrics( arguments.name, enabled );
44+
return enabled;
45+
}
46+
47+
public boolean function checkEnabled(
48+
required string name,
49+
struct additionalContext = {},
50+
boolean defaultValue = false
2151
) {
2252
var feature = getFeature( arguments.name );
2353
if ( isNull( feature ) ) {
@@ -131,6 +161,34 @@ component singleton accessors="true" {
131161
return features;
132162
}
133163

164+
public struct function sendMetrics() {
165+
var bucketToSend = variables.metricsBucket;
166+
variables.metricsBucket = newMetricsBucket();
167+
bucketToSend.stop = getIsoTimeString( now() );
168+
var metrics = {
169+
"appName" : variables.settings.appName,
170+
"instanceId" : variables.settings.instanceId,
171+
"bucket" : bucketToSend
172+
};
173+
variables.client.post( "/client/metrics", metrics );
174+
return metrics;
175+
}
176+
177+
private void function countForMetrics( required string name, required boolean enabled ) {
178+
if ( !variables.metricsBucket.toggles.keyExists( arguments.name ) ) {
179+
variables.metricsBucket.toggles[ arguments.name ] = { "yes" : 0, "no" : 0 };
180+
}
181+
variables.metricsBucket.toggles[ arguments.name ][ yesNoFormat( arguments.enabled ) ]++;
182+
}
183+
184+
public struct function newMetricsBucket() {
185+
return {
186+
"start" : getIsoTimeString( now() ),
187+
"stop" : "",
188+
"toggles" : {}
189+
};
190+
}
191+
134192
private array function fetchFeatures() {
135193
return variables.client.get( "/client/features" ).json().features;
136194
}
@@ -174,4 +232,15 @@ component singleton accessors="true" {
174232
return javacast( "null", "" );
175233
}
176234

235+
private string function getIsoTimeString( required date datetime, boolean convertToUTC = true ) {
236+
if ( arguments.convertToUTC ) {
237+
arguments.datetime = dateConvert( "local2utc", arguments.datetime );
238+
}
239+
240+
return dateFormat( arguments.datetime, "yyyy-mm-dd" ) &
241+
"T" &
242+
timeFormat( arguments.datetime, "HH:mm:ss" ) &
243+
"Z";
244+
}
245+
177246
}

0 commit comments

Comments
 (0)