|
8 | 8 | import org.apache.logging.log4j.Level;
|
9 | 9 | import org.apache.logging.log4j.Logger;
|
10 | 10 | import org.apache.logging.log4j.message.ParameterizedMessage;
|
11 |
| -import org.elasticsearch.common.ParsingException; |
| 11 | +import org.elasticsearch.ElasticsearchException; |
12 | 12 | import org.elasticsearch.common.Strings;
|
13 | 13 | import org.elasticsearch.common.bytes.BytesArray;
|
14 | 14 | import org.elasticsearch.common.bytes.BytesReference;
|
|
30 | 30 | import java.time.Instant;
|
31 | 31 | import java.time.temporal.ChronoUnit;
|
32 | 32 | import java.util.Deque;
|
| 33 | +import java.util.HashMap; |
| 34 | +import java.util.Locale; |
| 35 | +import java.util.Map; |
33 | 36 | import java.util.Objects;
|
34 | 37 | import java.util.concurrent.CountDownLatch;
|
35 | 38 | import java.util.concurrent.TimeUnit;
|
36 | 39 | import java.util.concurrent.TimeoutException;
|
| 40 | +import java.util.regex.Matcher; |
| 41 | +import java.util.regex.Pattern; |
37 | 42 |
|
38 | 43 | /**
|
39 | 44 | * Handle a stream of C++ log messages that arrive via a named pipe in JSON format.
|
@@ -181,6 +186,26 @@ public String getCppCopyright(Duration timeout) throws TimeoutException {
|
181 | 186 | return cppCopyright;
|
182 | 187 | }
|
183 | 188 |
|
| 189 | + /** |
| 190 | + * Extracts version information from the copyright string which assumes a certain format. |
| 191 | + */ |
| 192 | + public Map<String, Object> getNativeCodeInfo(Duration timeout) throws TimeoutException { |
| 193 | + String copyrightMessage = getCppCopyright(timeout); |
| 194 | + Matcher matcher = Pattern.compile("Version (.+) \\(Build ([^)]+)\\) Copyright ").matcher(copyrightMessage); |
| 195 | + if (matcher.find()) { |
| 196 | + Map<String, Object> info = new HashMap<>(2); |
| 197 | + info.put("version", matcher.group(1)); |
| 198 | + info.put("build_hash", matcher.group(2)); |
| 199 | + return info; |
| 200 | + } else { |
| 201 | + // If this happens it probably means someone has changed the format in lib/ver/CBuildInfo.cc |
| 202 | + // in the machine-learning-cpp repo without changing the pattern above to match |
| 203 | + String msg = "Unexpected native process copyright format: " + copyrightMessage; |
| 204 | + LOGGER.error(msg); |
| 205 | + throw new ElasticsearchException(msg); |
| 206 | + } |
| 207 | + } |
| 208 | + |
184 | 209 | /**
|
185 | 210 | * Expected to be called very infrequently.
|
186 | 211 | */
|
@@ -281,13 +306,14 @@ private void parseMessage(XContent xContent, BytesReference bytesRef) {
|
281 | 306 | } catch (XContentParseException e) {
|
282 | 307 | String upstreamMessage = "Fatal error: '" + bytesRef.utf8ToString() + "'";
|
283 | 308 | if (upstreamMessage.contains("bad_alloc")) {
|
284 |
| - upstreamMessage += ", process ran out of memory."; |
| 309 | + upstreamMessage += ", process ran out of memory"; |
285 | 310 | }
|
286 | 311 |
|
287 | 312 | // add version information, so it's conveniently next to the crash log
|
288 | 313 | upstreamMessage += ", version: ";
|
289 | 314 | try {
|
290 |
| - upstreamMessage += getCppCopyright(Duration.ofMillis(10)); |
| 315 | + Map<String, Object> versionInfo = getNativeCodeInfo(Duration.ofMillis(10)); |
| 316 | + upstreamMessage += String.format(Locale.ROOT, "%s (build %s)", versionInfo.get("version"), versionInfo.get("build_hash")); |
291 | 317 | } catch (TimeoutException timeoutException) {
|
292 | 318 | upstreamMessage += "failed to retrieve";
|
293 | 319 | }
|
|
0 commit comments