Skip to content

Commit 1a22356

Browse files
authored
Server telemetry (#850)
1 parent 7b9834a commit 1a22356

11 files changed

Lines changed: 54 additions & 30 deletions

grails-app/services/io/xh/toolbox/SlackAlertService.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import static io.xh.hoist.monitor.MonitorStatus.*
1414

1515
class SlackAlertService extends BaseService {
1616

17+
String telemetryPrefix = 'toolbox.slack'
18+
1719
ConfigService configService
1820

1921
void init() {
@@ -63,7 +65,7 @@ Time: ${tl.dateCreated.format('dd-MMM-yyyy HH:mm:ss')}
6365
}
6466

6567
private void sendSlackMessage(message) {
66-
span('toolbox.slack.sendMessage').run {
68+
span('sendMessage').run {
6769
def client = new JSONClient(),
6870
post = new HttpPost('https://slack.com/api/chat.postMessage'),
6971
body = JSONSerializer.serialize([channel: config.channel, text: message]),

grails-app/services/io/xh/toolbox/app/GitHubService.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import static io.xh.hoist.util.DateTimeUtils.MINUTES
3333
*/
3434
class GitHubService extends BaseService {
3535

36+
String telemetryPrefix = 'toolbox.github'
37+
3638
static clearCachesConfigs = ['gitHubRepos', 'gitHubAccessToken', 'gitHubMaxPagesPerLoad']
3739

3840
ConfigService configService
@@ -87,7 +89,7 @@ class GitHubService extends BaseService {
8789
def repos = configService.getList('gitHubRepos', []),
8890
newCommitCount = 0
8991

90-
span('toolbox.github.getCommits')
92+
span('getCommits')
9193
.logInfo("Refreshing GitHub commits for ${repos.size()} configured repositories")
9294
.run {
9395
repos.each {

grails-app/services/io/xh/toolbox/app/NewsService.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import static io.xh.hoist.util.DateTimeUtils.getMINUTES
1313

1414
class NewsService extends BaseService {
1515

16+
String telemetryPrefix = 'toolbox.news'
17+
1618
static clearCachesConfigs = ['newsSources', 'newsApiKey']
1719

1820
ConfigService configService
@@ -43,7 +45,7 @@ class NewsService extends BaseService {
4345
// Implementation
4446
//------------------------
4547
private List<NewsItem> loadNews() {
46-
span('toolbox.news.getNews').run {
48+
span('getNews').run {
4749
def sources = configService.getMap('newsSources').keySet().toList(),
4850
sourcesParam = sources.join(','),
4951
apiKey = configService.getString('newsApiKey'),

grails-app/services/io/xh/toolbox/app/RecallsService.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import static org.apache.hc.core5.http.HttpStatus.SC_OK
88

99
class RecallsService extends BaseService {
1010

11+
String telemetryPrefix = 'toolbox.recalls'
12+
1113
def configService
1214

1315
Integer lastResponseCode
1416
private JSONClient _jsonClient
1517

1618
List fetchRecalls(String searchQuery) {
17-
span('toolbox.recalls.get').run {
19+
span('get').run {
1820
def host = configService.getString('recallsHost'),
1921
uri = !searchQuery ?
2022
// `_exists_:openfda` ensures all search hits includes a nested openfda object that contains essential data for frontend

grails-app/services/io/xh/toolbox/app/WeatherService.groovy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import static io.xh.hoist.util.DateTimeUtils.MINUTES
1111

1212
class WeatherService extends BaseService {
1313

14+
String telemetryPrefix = 'toolbox.weather'
15+
1416
static clearCachesConfigs = ['weatherApiKey']
1517

1618
ConfigService configService
@@ -38,7 +40,7 @@ class WeatherService extends BaseService {
3840
encodedCity = URLEncoder.encode(city, 'UTF-8'),
3941
url = "https://api.openweathermap.org/data/2.5/weather?q=${encodedCity}&appid=${apiKey}&units=imperial"
4042

41-
span('toolbox.weather.getCurrent')
43+
span('getCurrent')
4244
.logDebug("Loading forecast for $city")
4345
.run {
4446
client.executeAsMap(new HttpGet(url))
@@ -50,7 +52,7 @@ class WeatherService extends BaseService {
5052
encodedCity = URLEncoder.encode(city, 'UTF-8'),
5153
url = "https://api.openweathermap.org/data/2.5/forecast?q=${encodedCity}&appid=${apiKey}&units=imperial"
5254

53-
span('toolbox.weather.getForecast')
55+
span('getForecast')
5456
.logDebug("Loading forecast for $city")
5557
.run {
5658
client.executeAsMap(new HttpGet(url))

grails-app/services/io/xh/toolbox/portfolio/PortfolioService.groovy

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package io.xh.toolbox.portfolio
22

33
import com.hazelcast.replicatedmap.ReplicatedMap
4-
import io.micrometer.core.instrument.Gauge
5-
import io.micrometer.core.instrument.Timer
64
import io.xh.hoist.BaseService
75
import io.xh.hoist.cachedvalue.CachedValue
86
import io.xh.hoist.exception.DataNotAvailableException
@@ -12,7 +10,6 @@ import java.time.*
1210

1311
import static io.xh.toolbox.portfolio.Utils.*
1412
import static io.xh.hoist.util.DateTimeUtils.SECONDS
15-
import static java.util.concurrent.TimeUnit.MILLISECONDS
1613

1714

1815
/**
@@ -26,17 +23,17 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS
2623
*/
2724
class PortfolioService extends BaseService {
2825

26+
String telemetryPrefix = 'toolbox.portfolio'
27+
28+
MetricsService metricsService
29+
2930
def configService,
3031
orderGenerationService,
3132
historicalPriceGenerationService,
3233
instrumentGenerationService
3334

34-
MetricsService metricsService
35-
3635
private CachedValue<Portfolio> _portfolio = createCachedValue(name: 'portfolio', replicate: true)
3736
private ReplicatedMap<String, MarketPrice> _currentPrices = createReplicatedMap('currentPrices')
38-
private Timer generationTimer
39-
private Gauge positionsGauge
4037

4138
void init() {
4239
initMetrics()
@@ -79,16 +76,24 @@ class PortfolioService extends BaseService {
7976
// Implementation
8077
//------------------------
8178
private void initMetrics() {
82-
def registry = metricsService.registry
79+
metricsService.registerGauge(
80+
name: 'position.count',
81+
description: 'Number of portfolio positions',
82+
valueFn: { _portfolio.get()?.rawPositions?.size() ?: 0 },
83+
owner: this
84+
)
8385

84-
positionsGauge = Gauge.builder('toolbox.portfolio.positions', this) {
85-
(_portfolio.get()?.rawPositions?.size() ?: 0) as double
86-
}.description('Number of portfolio positions')
87-
.register(registry)
86+
metricsService.configureTimer(
87+
name: 'generation.time',
88+
description: 'Time to generate portfolio',
89+
owner: this
90+
)
8891

89-
generationTimer = Timer.builder('toolbox.portfolio.generationTime')
90-
.description('Time to generate portfolio')
91-
.register(registry)
92+
metricsService.configureCounter(
93+
name: 'generation.count',
94+
description: 'The number of portfolio generations',
95+
owner: this
96+
)
9297
}
9398

9499
private void updateData(boolean force = false) {
@@ -126,9 +131,10 @@ class PortfolioService extends BaseService {
126131

127132
private Portfolio generatePortfolio() {
128133
observe()
129-
.span(name: 'generatePortfolio')
134+
.span('generatePortfolio')
135+
.timer('generation.time')
136+
.counter('generation.count')
130137
.logInfo('Generating Portfolio')
131-
.timer(generationTimer)
132138
.run {
133139
def day = LocalDate.now(),
134140
instruments = instrumentGenerationService.generateInstruments(),
@@ -183,8 +189,6 @@ class PortfolioService extends BaseService {
183189
def p = _portfolio.get()
184190
return [
185191
config: configForAdminStats('portfolioConfigs'),
186-
avgGenerationTime: generationTimer.mean(MILLISECONDS),
187-
188192
portfolioAvailable: portfolioAvailable,
189193
day: p?.day,
190194
generatedAt: p?.timeCreated,

grails-app/services/io/xh/toolbox/portfolio/generation/HistoricalPriceGenerationService.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import static io.xh.toolbox.portfolio.Utils.randInt
1717
*/
1818
class HistoricalPriceGenerationService extends BaseService {
1919

20+
String telemetryPrefix = 'toolbox.portfolio'
21+
2022
def tradingDayService
2123

2224
/** Generate a daily price series for each instrument, keyed by symbol. */
@@ -25,7 +27,7 @@ class HistoricalPriceGenerationService extends BaseService {
2527
LocalDate day
2628
) {
2729
observe()
28-
.span(name: 'generateHistoricalPrices')
30+
.span('generateHistoricalPrices')
2931
.logDebug("Generating historical prices for ${instruments.size()} instruments")
3032
.run {
3133
List<LocalDate> tradingDays = tradingDayService.historicalDays(day)

grails-app/services/io/xh/toolbox/portfolio/generation/InstrumentGenerationService.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ import static io.xh.toolbox.portfolio.Utils.sample
1515
*/
1616
class InstrumentGenerationService extends BaseService {
1717

18+
String telemetryPrefix = 'toolbox.portfolio'
19+
1820
def configService
1921

2022
/** Generate a map of unique instruments keyed by ticker symbol. */
2123
Map<String, Instrument> generateInstruments() {
2224
observe()
23-
.span(name: 'generateInstruments')
25+
.span('generateInstruments')
2426
.logDebug("Generating ${config.instrumentCount} instruments")
2527
.run {
2628
def instrumentCount = config.instrumentCount

grails-app/services/io/xh/toolbox/portfolio/generation/OrderGenerationService.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import static io.xh.toolbox.portfolio.Lookups.*
2222
*/
2323
class OrderGenerationService extends BaseService {
2424

25+
String telemetryPrefix = 'toolbox.portfolio'
26+
2527
def configService
2628

2729
private static final ZoneOffset EST = ZoneOffset.ofHours(-5)
@@ -33,7 +35,7 @@ class OrderGenerationService extends BaseService {
3335
Map<String, List<MarketPrice>> historicalPrices
3436
) {
3537
observe()
36-
.span(name: 'generateOrders')
38+
.span('generateOrders')
3739
.logDebug("Generating ${config.orderCount} orders")
3840
.run {
3941
def orderCount = config.orderCount

grails-app/services/io/xh/toolbox/security/AuthZeroTokenService.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import static java.lang.System.currentTimeMillis
1616
*/
1717
class AuthZeroTokenService extends BaseService {
1818

19+
String telemetryPrefix = 'toolbox.auth'
20+
1921
static clearCachesConfigs = ['auth0Config']
2022

2123
AuthenticationService authenticationService
@@ -91,7 +93,7 @@ class AuthZeroTokenService extends BaseService {
9193

9294
private JsonWebKeySet createKeySet() {
9395
def url = "https://$domain/.well-known/jwks.json"
94-
span('toolbox.auth.getAuth0JWKS')
96+
span('getAuth0JWKS')
9597
.logInfo(['Fetching JWKS', url])
9698
.run {
9799
def jwksJson = (new JSONClient()).executeAsString(new HttpGet(url)),

0 commit comments

Comments
 (0)