Skip to content

Commit 1d34547

Browse files
committed
Fix #27089: Allow to use multiple statistics backends
1 parent c29c693 commit 1d34547

5 files changed

Lines changed: 115 additions & 84 deletions

File tree

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2021 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.stat;
22+
23+
import eu.openanalytics.containerproxy.stat.impl.InfluxDBCollector;
24+
import eu.openanalytics.containerproxy.stat.impl.JDBCCollector;
25+
import eu.openanalytics.containerproxy.stat.impl.Micrometer;
26+
import org.apache.logging.log4j.LogManager;
27+
import org.apache.logging.log4j.Logger;
28+
import org.springframework.beans.BeansException;
29+
import org.springframework.beans.factory.config.BeanDefinition;
30+
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
31+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
32+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
33+
import org.springframework.beans.factory.support.GenericBeanDefinition;
34+
import org.springframework.context.EnvironmentAware;
35+
import org.springframework.core.env.Environment;
36+
import org.springframework.stereotype.Component;
37+
38+
import javax.annotation.Nonnull;
39+
40+
@Component
41+
public class StatCollectorFactory implements BeanFactoryPostProcessor, EnvironmentAware {
42+
43+
private final Logger log = LogManager.getLogger(StatCollectorFactory.class);
44+
45+
private static final String PROP_USAGE_STATS_MULTI_URL = "proxy.usage-stats[%d].url";
46+
private static final String PROP_USAGE_STATS_MULTI_USERNAME = "proxy.usage-stats[%d].username";
47+
private static final String PROP_USAGE_STATS_MULTI_PASSWORD = "proxy.usage-stats[%d].password";
48+
49+
private Environment environment;
50+
51+
@Override
52+
public void postProcessBeanFactory(@Nonnull ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
53+
DefaultListableBeanFactory registry = (DefaultListableBeanFactory) configurableListableBeanFactory;
54+
55+
int i = 0;
56+
String usageStatsUrl = environment.getProperty(String.format(PROP_USAGE_STATS_MULTI_URL, i));
57+
while (usageStatsUrl != null) {
58+
String username = environment.getProperty(String.format(PROP_USAGE_STATS_MULTI_USERNAME, i));
59+
String password = environment.getProperty(String.format(PROP_USAGE_STATS_MULTI_PASSWORD, i));
60+
createCollector(registry, usageStatsUrl, username, password);
61+
62+
i++;
63+
usageStatsUrl = environment.getProperty(String.format(PROP_USAGE_STATS_MULTI_URL, i));
64+
}
65+
66+
String baseURL = environment.getProperty("proxy.usage-stats-url");
67+
if (baseURL != null && !baseURL.isEmpty()) {
68+
String username = environment.getProperty("proxy.usage-stats-username");
69+
String password = environment.getProperty("proxy.usage-stats-password");
70+
createCollector(registry, baseURL, username, password);
71+
}
72+
}
73+
74+
private void createCollector(DefaultListableBeanFactory registry, String url, String username, String password) {
75+
log.info(String.format("Enabled. Sending usage statistics to %s.", url));
76+
77+
BeanDefinition bd = new GenericBeanDefinition();
78+
if (url.toLowerCase().contains("/write?db=")) {
79+
bd.setBeanClassName(InfluxDBCollector.class.getName());
80+
bd.getConstructorArgumentValues().addGenericArgumentValue(url);
81+
} else if (url.toLowerCase().startsWith("jdbc")) {
82+
bd.setBeanClassName(JDBCCollector.class.getName());
83+
bd.getConstructorArgumentValues().addGenericArgumentValue(url);
84+
bd.getConstructorArgumentValues().addGenericArgumentValue(username);
85+
bd.getConstructorArgumentValues().addGenericArgumentValue(password);
86+
} else if (url.equalsIgnoreCase("micrometer")) {
87+
bd.setBeanClassName(Micrometer.class.getName());
88+
} else {
89+
throw new IllegalArgumentException(String.format("Base url for statistics contains an unrecognized values, baseURL %s.", url));
90+
}
91+
92+
registry.registerBeanDefinition(url, bd);
93+
}
94+
95+
@Override
96+
public void setEnvironment(Environment environment) {
97+
this.environment = environment;
98+
}
99+
}

src/main/java/eu/openanalytics/containerproxy/stat/StatCollectorRegistry.java

Lines changed: 0 additions & 67 deletions
This file was deleted.

src/main/java/eu/openanalytics/containerproxy/stat/impl/AbstractDbCollector.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,12 @@ public abstract class AbstractDbCollector implements IStatCollector {
3232

3333
@EventListener
3434
public void onUserLogoutEvent(UserLogoutEvent event) throws IOException {
35-
if (event.getSource().equals(SOURCE_NOT_AVAILABLE)) {
36-
writeToDb(event.getTimestamp(), event.getUserId(), "Logout", null);
37-
}
35+
writeToDb(event.getTimestamp(), event.getUserId(), "Logout", null);
3836
}
3937

4038
@EventListener
4139
public void onUserLoginEvent(UserLoginEvent event) throws IOException {
42-
if (event.getSource().equals(SOURCE_NOT_AVAILABLE)) {
43-
writeToDb(event.getTimestamp(), event.getUserId(), "Login", null);
44-
}
40+
writeToDb(event.getTimestamp(), event.getUserId(), "Login", null);
4541
}
4642

4743
@EventListener

src/main/java/eu/openanalytics/containerproxy/stat/impl/InfluxDBCollector.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,12 @@
3939
*/
4040
public class InfluxDBCollector extends AbstractDbCollector {
4141

42-
private String destination;
42+
private final String destination;
4343

44-
@PostConstruct
45-
public void init() {
46-
destination = environment.getProperty("proxy.usage-stats-url");
44+
public InfluxDBCollector(String url) {
45+
destination = url;
4746
}
4847

49-
@Inject
50-
private Environment environment;
51-
5248
@Override
5349
protected void writeToDb(long timestamp, String userId, String type, String data) throws IOException {
5450
String body = String.format("event,username=%s,type=%s data=\"%s\"",

src/main/java/eu/openanalytics/containerproxy/stat/impl/JDBCCollector.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,20 @@ public class JDBCCollector extends AbstractDbCollector {
6363
@Inject
6464
private Environment environment;
6565

66+
private final String url;
67+
private final String username;
68+
private final String password;
69+
70+
public JDBCCollector(String url, String username, String password) {
71+
this.url = url;
72+
this.username = username;
73+
this.password = password;
74+
}
75+
6676
@PostConstruct
6777
public void init() throws IOException {
68-
String baseURL = environment.getProperty("proxy.usage-stats-url");
69-
String username = environment.getProperty("proxy.usage-stats-username", "monetdb");
70-
String password = environment.getProperty("proxy.usage-stats-password", "monetdb");
7178
ds = new HikariDataSource();
72-
ds.setJdbcUrl(baseURL);
79+
ds.setJdbcUrl(url);
7380
ds.setUsername(username);
7481
ds.setPassword(password);
7582

0 commit comments

Comments
 (0)