-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathInstallTelemetryBootstrap.java
More file actions
136 lines (120 loc) · 5.54 KB
/
Copy pathInstallTelemetryBootstrap.java
File metadata and controls
136 lines (120 loc) · 5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package com.dbaagent.service.telemetry;
import com.dbaagent.model.InstallTelemetryIdentity;
import com.dbaagent.repository.InstallTelemetryIdentityRepository;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.security.SecureRandom;
import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.HexFormat;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@Component
@RequiredArgsConstructor
@Slf4j
public class InstallTelemetryBootstrap {
private static final SecureRandom RANDOM = new SecureRandom();
private static final int SECRET_BYTES = 32;
private static final int TOKEN_RANDOM_BYTES = 28;
private static final String TOKEN_PREFIX = "dt_live_";
private static final String UNKNOWN_COMPANY = "unknown";
/**
* Email domains we won't infer as company names from the admin email
* fallback. Mostly consumer freemail providers + localhost/dev domains.
*/
static final Set<String> FREEMAIL_DOMAINS = Set.of(
"gmail.com", "googlemail.com", "yahoo.com", "hotmail.com",
"outlook.com", "icloud.com", "me.com", "protonmail.com",
"aol.com", "mail.com", "localhost", "dba-agent.local");
private final InstallTelemetryIdentityRepository repository;
private final TelemetryClient telemetryClient;
@PostConstruct
@Transactional
public void bootstrap() {
InstallTelemetryIdentity identity = repository.findById(1).orElse(null);
if (identity == null) {
identity = buildNewIdentity();
try {
repository.save(identity);
repository.flush();
} catch (DataIntegrityViolationException e) {
// Another JVM beat us to the singleton row (concurrent start,
// blue-green deploy, rolling restart). That instance owns the
// report — do not emit, do not throw.
log.info("InstallTelemetryBootstrap: identity created by a peer JVM, skipping");
return;
}
log.info("InstallTelemetryBootstrap: new install identity created, install_id={}",
identity.getInstallId());
}
// Report install.bootstrapped whenever it has NOT yet been reported.
// Gating on bootstrap_reported_at (not on "the row is brand new") is the
// fix for installs that go untracked in PostHog: an identity row created
// while the sink was NoOp (the 2026-05-23..05-26 key-rollout window), or
// carried forward on a reused/persistent volume, still emits the "new
// install" signal on its next start instead of being invisible forever.
if (identity.getBootstrapReportedAt() == null) {
Map<String, Object> props = new HashMap<>();
props.put("install_method", detectInstallMethod());
props.put("os", System.getProperty("os.name", "unknown"));
props.put("arch", System.getProperty("os.arch", "unknown"));
telemetryClient.capture("install.bootstrapped", props);
identity.setBootstrapReportedAt(OffsetDateTime.now());
repository.save(identity);
log.info("InstallTelemetryBootstrap: install.bootstrapped reported, install_id={}",
identity.getInstallId());
} else {
log.debug("InstallTelemetryBootstrap: install.bootstrapped already reported, skipping");
}
}
private InstallTelemetryIdentity buildNewIdentity() {
byte[] secret = new byte[SECRET_BYTES];
RANDOM.nextBytes(secret);
byte[] tokenRandom = new byte[TOKEN_RANDOM_BYTES];
RANDOM.nextBytes(tokenRandom);
String token = TOKEN_PREFIX + HexFormat.of().formatHex(tokenRandom);
String companyName = resolveCompanyName(
System.getenv("DEEPSQL_COMPANY_NAME"),
System.getenv("DEEPSQL_INITIAL_ADMIN_EMAIL"));
return InstallTelemetryIdentity.builder()
.id(1)
.installId(UUID.randomUUID())
.installSecret(secret)
.installToken(token)
.companyName(companyName)
.createdAt(OffsetDateTime.now())
.build();
}
private String detectInstallMethod() {
String m = System.getenv("DEEPSQL_INSTALL_METHOD");
return (m == null || m.isBlank()) ? "unknown" : m;
}
/**
* Resolves the company_name attached to this install's identity.
*
* Precedence:
* 1. explicit {@code DEEPSQL_COMPANY_NAME} env var (operator-supplied)
* 2. domain part of the admin email, if not a freemail/localhost domain
* 3. {@code "unknown"} sentinel
*
* Package-private so {@code InstallTelemetryBootstrapTest} can exercise
* the precedence rules directly without touching {@code System.getenv}.
*/
static String resolveCompanyName(String explicitEnv, String adminEmail) {
if (explicitEnv != null && !explicitEnv.isBlank()) {
return explicitEnv.trim();
}
if (adminEmail != null && adminEmail.indexOf('@') > 0) {
String domain = adminEmail.substring(adminEmail.indexOf('@') + 1).trim().toLowerCase();
if (!domain.isEmpty() && !FREEMAIL_DOMAINS.contains(domain)) {
return domain;
}
}
return UNKNOWN_COMPANY;
}
}