diff options
author | Valerij Fredriksen <valerijf@yahooinc.com> | 2023-04-13 15:35:22 +0200 |
---|---|---|
committer | Valerij Fredriksen <valerijf@yahooinc.com> | 2023-04-13 15:35:22 +0200 |
commit | 13ca620e8868b0be2ab961bba12bd2b8840729bc (patch) | |
tree | f50576586ebdb94e64b97cfaf0132ef006b4f102 /node-admin | |
parent | 2fe8417832a525f749b0e563615f628e5645aac0 (diff) |
Report core created timestamp as last modified time
Diffstat (limited to 'node-admin')
5 files changed, 39 insertions, 5 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoreDumpMetadata.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoreDumpMetadata.java index eceb83a6cba..92cccf86ecb 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoreDumpMetadata.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoreDumpMetadata.java @@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.node.admin.configserver.cores; import com.yahoo.config.provision.DockerImage; import java.nio.file.Path; +import java.time.Instant; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -16,6 +17,7 @@ public class CoreDumpMetadata { private Type type; private String binPath; + private Instant created; private List<String> backtrace; private List<String> backtraceAllThreads; private Path coreDumpPath; @@ -29,6 +31,7 @@ public class CoreDumpMetadata { public Optional<Type> type() { return Optional.ofNullable(type); } public Optional<String> binPath() { return Optional.ofNullable(binPath); } + public Optional<Instant> created() { return Optional.ofNullable(created); } public Optional<List<String>> backtrace() { return Optional.ofNullable(backtrace); } public Optional<List<String>> backtraceAllThreads() { return Optional.ofNullable(backtraceAllThreads); } public Optional<Path> coredumpPath() { return Optional.ofNullable(coreDumpPath); } @@ -40,6 +43,7 @@ public class CoreDumpMetadata { public CoreDumpMetadata setType(Type type) { this.type = type; return this; } public CoreDumpMetadata setBinPath(String binPath) { this.binPath = binPath; return this; } + public CoreDumpMetadata setCreated(Instant created) { this.created = created; return this; } public CoreDumpMetadata setBacktrace(List<String> backtrace) { this.backtrace = backtrace; return this; } public CoreDumpMetadata setBacktraceAllThreads(List<String> backtraceAllThreads) { this.backtraceAllThreads = backtraceAllThreads; return this; } public CoreDumpMetadata setCoreDumpPath(Path coreDumpPath) { this.coreDumpPath = coreDumpPath; return this; } @@ -54,6 +58,7 @@ public class CoreDumpMetadata { return "CoreDumpMetadata{" + "type=" + type + ", binPath=" + binPath + + ", created=" + created + ", backtrace=" + backtrace + ", backtraceAllThreads=" + backtraceAllThreads + ", coreDumpPath=" + coreDumpPath + @@ -72,6 +77,7 @@ public class CoreDumpMetadata { CoreDumpMetadata metadata = (CoreDumpMetadata) o; return type == metadata.type && Objects.equals(binPath, metadata.binPath) && + Objects.equals(created, metadata.created) && Objects.equals(backtrace, metadata.backtrace) && Objects.equals(backtraceAllThreads, metadata.backtraceAllThreads) && Objects.equals(coreDumpPath, metadata.coreDumpPath) && @@ -84,7 +90,7 @@ public class CoreDumpMetadata { @Override public int hashCode() { - return Objects.hash(type, binPath, backtrace, backtraceAllThreads, coreDumpPath, decryptionToken, kernelVersion, + return Objects.hash(type, binPath, created, backtrace, backtraceAllThreads, coreDumpPath, decryptionToken, kernelVersion, cpuMicrocodeVersion, dockerImage, vespaVersion); } } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/bindings/ReportCoreDumpRequest.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/bindings/ReportCoreDumpRequest.java index cf717aff787..a9620ebabc2 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/bindings/ReportCoreDumpRequest.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/bindings/ReportCoreDumpRequest.java @@ -14,6 +14,7 @@ import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; +import java.time.Instant; import java.util.List; import java.util.Optional; @@ -31,6 +32,7 @@ public class ReportCoreDumpRequest { public List<String> backtrace; public List<String> backtrace_all_threads; + public Long created; public String type; public String bin_path; public String coredump_path; @@ -47,6 +49,7 @@ public class ReportCoreDumpRequest { public ReportCoreDumpRequest fillFrom(CoreDumpMetadata metadata) { metadata.type().ifPresent(type -> this.type = type.name()); metadata.binPath().ifPresent(binPath -> this.bin_path = binPath); + metadata.created().ifPresent(created -> this.created = created.toEpochMilli()); metadata.backtrace().ifPresent(backtrace -> this.backtrace = List.copyOf(backtrace)); metadata.backtraceAllThreads().ifPresent(backtraceAllThreads -> this.backtrace_all_threads = List.copyOf(backtraceAllThreads)); metadata.coredumpPath().ifPresent(coredumpPath -> this.coredump_path = coredumpPath.toString()); @@ -60,7 +63,9 @@ public class ReportCoreDumpRequest { @JsonIgnore public void populateMetadata(CoreDumpMetadata metadata, FileSystem fileSystem) { + if (type != null) metadata.setType(CoreDumpMetadata.Type.valueOf(type)); if (bin_path != null) metadata.setBinPath(bin_path); + if (created != null) metadata.setCreated(Instant.ofEpochMilli(created)); if (backtrace != null) metadata.setBacktrace(backtrace); if (backtrace_all_threads != null) metadata.setBacktraceAllThreads(backtrace_all_threads); if (coredump_path != null) metadata.setCoreDumpPath(fileSystem.getPath(coredump_path)); diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoreCollector.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoreCollector.java index 4761b6da421..5d4628b41b6 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoreCollector.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoreCollector.java @@ -5,6 +5,7 @@ import com.yahoo.vespa.hosted.node.admin.configserver.cores.CoreDumpMetadata; import com.yahoo.vespa.hosted.node.admin.container.ContainerOperations; import com.yahoo.vespa.hosted.node.admin.nodeadmin.ConvergenceException; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContext; +import com.yahoo.vespa.hosted.node.admin.task.util.file.UnixPath; import com.yahoo.vespa.hosted.node.admin.task.util.fs.ContainerPath; import com.yahoo.vespa.hosted.node.admin.task.util.process.CommandResult; @@ -96,7 +97,8 @@ public class CoreCollector { } CoreDumpMetadata collect(NodeAgentContext context, ContainerPath coredumpPath) { - var metadata = new CoreDumpMetadata(); + var metadata = new CoreDumpMetadata() + .setCreated(new UnixPath(coredumpPath).getLastModifiedTime()); if (JAVA_HEAP_DUMP_PATTERN.matcher(coredumpPath.getFileName().toString()).find()) { metadata.setType(CoreDumpMetadata.Type.JVM_HEAP) diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoresTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoresTest.java index f49dd2e705b..b35f4d6c790 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoresTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoresTest.java @@ -16,6 +16,7 @@ import org.mockito.ArgumentCaptor; import java.nio.file.FileSystem; import java.nio.file.Path; +import java.time.Instant; import java.util.List; import java.util.Optional; @@ -40,6 +41,8 @@ class CoresTest { private final HostName hostname = HostName.of("foo.com"); private final String id = "5c987afb-347a-49ee-a0c5-bef56bbddeb0"; private final CoreDumpMetadata metadata = new CoreDumpMetadata() + .setType(CoreDumpMetadata.Type.OOM) + .setCreated(Instant.ofEpochMilli(12345678)) .setKernelVersion("4.18.0-372.26.1.el8_6.x86_64") .setCpuMicrocodeVersion("0x1000065") .setCoreDumpPath(fileSystem.getPath("/data/vespa/processed-coredumps/h7641a/5c987afb-347a-49ee-a0c5-bef56bbddeb0/dump_java.core.813")) @@ -83,9 +86,11 @@ class CoresTest { "bin_path": "/usr/bin/java", "coredump_path": "/data/vespa/processed-coredumps/h7641a/5c987afb-347a-49ee-a0c5-bef56bbddeb0/dump_java.core.813", "cpu_microcode_version": "0x1000065", + "created": 12345678, "decryption_token": "987def", "docker_image": "us-central1-docker.pkg.dev/vespa-external-cd/vespa-cloud/vespa/cloud-tenant-rhel8:8.68.8", "kernel_version": "4.18.0-372.26.1.el8_6.x86_64", + "type": "OOM", "vespa_version": "8.68.8" }""", JsonTestHelper.normalize(uncheck(() -> mapper.writeValueAsString(bodyJsonPojoCaptor.getValue())))); @@ -128,9 +133,11 @@ class CoresTest { "bin_path": "/usr/bin/java", "coredump_path": "/data/vespa/processed-coredumps/h7641a/5c987afb-347a-49ee-a0c5-bef56bbddeb0/dump_java.core.813", "cpu_microcode_version": "0x1000065", + "created": 12345678, "decryption_token": "987def", "docker_image": "us-central1-docker.pkg.dev/vespa-external-cd/vespa-cloud/vespa/cloud-tenant-rhel8:8.68.8", "kernel_version": "4.18.0-372.26.1.el8_6.x86_64", + "type": "OOM", "vespa_version": "8.68.8" }""", JsonTestHelper.normalize(new UnixPath(path).readUtf8File())); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoreCollectorTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoreCollectorTest.java index 2ca9e084d96..b4a35d6012c 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoreCollectorTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/coredump/CoreCollectorTest.java @@ -5,11 +5,13 @@ import com.yahoo.vespa.hosted.node.admin.configserver.cores.CoreDumpMetadata; import com.yahoo.vespa.hosted.node.admin.container.ContainerOperations; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContext; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContextImpl; +import com.yahoo.vespa.hosted.node.admin.task.util.file.UnixPath; import com.yahoo.vespa.hosted.node.admin.task.util.fs.ContainerPath; import com.yahoo.vespa.hosted.node.admin.task.util.process.CommandResult; import com.yahoo.vespa.test.file.TestFileSystem; import org.junit.jupiter.api.Test; +import java.time.Instant; import java.util.List; import static com.yahoo.vespa.hosted.node.admin.maintenance.coredump.CoreCollector.GDB_PATH_RHEL8; @@ -22,12 +24,18 @@ import static org.mockito.Mockito.when; * @author freva */ public class CoreCollectorTest { + private static final Instant CORE_CREATED = Instant.ofEpochMilli(2233445566L); + private final ContainerOperations docker = mock(ContainerOperations.class); private final CoreCollector coreCollector = new CoreCollector(docker); private final NodeAgentContext context = NodeAgentContextImpl.builder("container-123.domain.tld") .fileSystem(TestFileSystem.create()).build(); - private final ContainerPath TEST_CORE_PATH = context.paths().of("/tmp/core.1234"); + private final ContainerPath TEST_CORE_PATH = (ContainerPath) new UnixPath(context.paths().of("/tmp/core.1234")) + .createParents() + .createNewFile() + .setLastModifiedTime(CORE_CREATED) + .toPath(); private final String TEST_BIN_PATH = "/usr/bin/program"; private final List<String> GDB_BACKTRACE = List.of("[New Thread 2703]", "Core was generated by `/usr/bin/program\'.", "Program terminated with signal 11, Segmentation fault.", @@ -143,6 +151,7 @@ public class CoreCollectorTest { String.join("\n", GDB_BACKTRACE)); var expected = new CoreDumpMetadata().setBinPath(TEST_BIN_PATH) + .setCreated(CORE_CREATED) .setType(CoreDumpMetadata.Type.CORE_DUMP) .setBacktrace(GDB_BACKTRACE) .setBacktraceAllThreads(GDB_BACKTRACE); @@ -157,7 +166,7 @@ public class CoreCollectorTest { mockExec(new String[]{GDB_PATH_RHEL8 + " -n -ex set print frame-arguments none -ex bt -batch /usr/bin/program /tmp/core.1234"}, "", "Failure"); - var expected = new CoreDumpMetadata().setBinPath(TEST_BIN_PATH).setType(CoreDumpMetadata.Type.CORE_DUMP); + var expected = new CoreDumpMetadata().setBinPath(TEST_BIN_PATH).setCreated(CORE_CREATED).setType(CoreDumpMetadata.Type.CORE_DUMP); assertEquals(expected, coreCollector.collect(context, TEST_CORE_PATH)); } @@ -175,6 +184,7 @@ public class CoreCollectorTest { jstack); var expected = new CoreDumpMetadata().setBinPath(jdkPath) + .setCreated(CORE_CREATED) .setType(CoreDumpMetadata.Type.CORE_DUMP) .setBacktraceAllThreads(List.of(jstack)); assertEquals(expected, coreCollector.collect(context, TEST_CORE_PATH)); @@ -184,9 +194,13 @@ public class CoreCollectorTest { void metadata_for_java_heap_dump() { var expected = new CoreDumpMetadata().setBinPath("java") .setType(CoreDumpMetadata.Type.JVM_HEAP) + .setCreated(CORE_CREATED) .setBacktrace(List.of("Heap dump, no backtrace available")); - assertEquals(expected, coreCollector.collect(context, context.paths().of("/dump_java_pid123.hprof"))); + assertEquals(expected, coreCollector.collect(context, (ContainerPath) new UnixPath(context.paths().of("/dump_java_pid123.hprof")) + .createNewFile() + .setLastModifiedTime(CORE_CREATED) + .toPath())); } private void mockExec(String[] cmd, String output) { |