Search in sources :

Example 1 with LogLineBatch

use of com.facebook.buck.distributed.thrift.LogLineBatch in project buck by facebook.

the class DistBuildLogStateTracker method processStreamLogs.

/*
   *******************************
   *  Helpers
   *******************************
   */
private void processStreamLogs(StreamLogs streamLogs) {
    if (!seenSlaveLogs.containsKey(streamLogs.slaveStream)) {
        seenSlaveLogs.put(streamLogs.slaveStream, new SlaveStreamState());
    }
    SlaveStreamState seenStreamState = Preconditions.checkNotNull(seenSlaveLogs.get(streamLogs.slaveStream));
    LogLineBatch lastReceivedBatch = streamLogs.logLineBatches.get(streamLogs.logLineBatches.size() - 1);
    if (seenStreamState.seenBatchNumber > lastReceivedBatch.batchNumber || (seenStreamState.seenBatchNumber == lastReceivedBatch.batchNumber && seenStreamState.seenBatchLineCount >= lastReceivedBatch.lines.size())) {
        LOG.warn("Received stale logs for runID [%s] and stream [%s]", streamLogs.slaveStream.runId, streamLogs.slaveStream.streamType);
        return;
    }
    // Determines which log lines need writing, and then writes them to disk.
    List<String> newLines = Lists.newArrayList();
    for (LogLineBatch batch : streamLogs.logLineBatches) {
        if (batch.batchNumber < seenStreamState.seenBatchNumber) {
            continue;
        }
        if (batch.batchNumber == seenStreamState.seenBatchNumber) {
            if (batch.lines.size() == seenStreamState.seenBatchLineCount) {
                continue;
            }
            newLines.addAll(batch.lines.subList(seenStreamState.seenBatchLineCount, batch.lines.size()));
        } else {
            newLines.addAll(batch.lines);
        }
    }
    writeLogStreamLinesToDisk(streamLogs.slaveStream, newLines);
    seenStreamState.seenBatchNumber = lastReceivedBatch.batchNumber;
    seenStreamState.seenBatchLineCount = lastReceivedBatch.lines.size();
}
Also used : LogLineBatch(com.facebook.buck.distributed.thrift.LogLineBatch)

Example 2 with LogLineBatch

use of com.facebook.buck.distributed.thrift.LogLineBatch in project buck by facebook.

the class DistBuildLogStateTrackerTest method testStreamsLogsForRuns.

@Test
public void testStreamsLogsForRuns() throws IOException {
    BuildSlaveInfo runOneSlaveInfo = new BuildSlaveInfo();
    RunId runOneId = new RunId();
    runOneId.setId(RUN_ONE_ID);
    runOneSlaveInfo.setRunId(runOneId);
    runOneSlaveInfo.setStdOutCurrentBatchNumber(0);
    runOneSlaveInfo.setStdOutCurrentBatchLineCount(0);
    runOneSlaveInfo.setStdErrCurrentBatchNumber(1);
    runOneSlaveInfo.setStdErrCurrentBatchLineCount(1);
    BuildSlaveInfo runTwoSlaveInfo = new BuildSlaveInfo();
    RunId runTwoId = new RunId();
    runTwoId.setId(RUN_TWO_ID);
    runTwoSlaveInfo.setRunId(runTwoId);
    runTwoSlaveInfo.setStdOutCurrentBatchNumber(2);
    runTwoSlaveInfo.setStdOutCurrentBatchLineCount(2);
    runTwoSlaveInfo.setStdErrCurrentBatchNumber(0);
    runTwoSlaveInfo.setStdErrCurrentBatchLineCount(0);
    // runOne has stdErr, and runTwo has stdOut to download.
    List<BuildSlaveInfo> buildSlaveInfos = ImmutableList.of(runOneSlaveInfo, runTwoSlaveInfo);
    List<LogLineBatchRequest> requestsOne = distBuildLogStateTracker.createRealtimeLogRequests(buildSlaveInfos);
    assertThat(requestsOne.size(), Matchers.equalTo(2));
    // Request runOne/stdErr from batch 1
    assertTrue(requestsOne.stream().anyMatch(r -> r.slaveStream.runId.equals(runOneId) && r.slaveStream.streamType.equals(LogStreamType.STDERR) && r.batchNumber == 1));
    // Request runTwo/stdOut from batch 1
    assertTrue(requestsOne.stream().anyMatch(r -> r.slaveStream.runId.equals(runTwoId) && r.slaveStream.streamType.equals(LogStreamType.STDOUT) && r.batchNumber == 1));
    // Process new logs
    SlaveStream runOneStdErrStream = new SlaveStream();
    runOneStdErrStream.setRunId(runOneId);
    runOneStdErrStream.setStreamType(LogStreamType.STDERR);
    SlaveStream runOneStdOutStream = new SlaveStream();
    runOneStdOutStream.setRunId(runOneId);
    runOneStdOutStream.setStreamType(LogStreamType.STDOUT);
    SlaveStream runTwoStdOutStream = new SlaveStream();
    runTwoStdOutStream.setRunId(runTwoId);
    runTwoStdOutStream.setStreamType(LogStreamType.STDOUT);
    StreamLogs runOneStdErrLogs = new StreamLogs();
    runOneStdErrLogs.setSlaveStream(runOneStdErrStream);
    LogLineBatch runOneStdErrLogsBatchOne = new LogLineBatch();
    runOneStdErrLogsBatchOne.setBatchNumber(1);
    runOneStdErrLogsBatchOne.setLines(ImmutableList.of("runOneStdErrLine1\n", "runOneStdErrLine2\n"));
    runOneStdErrLogs.setLogLineBatches(ImmutableList.of(runOneStdErrLogsBatchOne));
    StreamLogs runTwoStdOutLogs = new StreamLogs();
    runTwoStdOutLogs.setSlaveStream(runTwoStdOutStream);
    LogLineBatch runTwoStdOutLogsBatchOne = new LogLineBatch();
    runTwoStdOutLogsBatchOne.setBatchNumber(1);
    runTwoStdOutLogsBatchOne.setLines(ImmutableList.of("runTwoStdOutLine1\n"));
    LogLineBatch runTwoStdOutLogsBatchTwo = new LogLineBatch();
    runTwoStdOutLogsBatchTwo.setBatchNumber(2);
    runTwoStdOutLogsBatchTwo.setLines(ImmutableList.of("runTwoStdOutLine2\n", "runTwoStdOutLine3\n"));
    runTwoStdOutLogs.setLogLineBatches(ImmutableList.of(runTwoStdOutLogsBatchOne, runTwoStdOutLogsBatchTwo));
    List<StreamLogs> streamLogsOne = ImmutableList.of(runOneStdErrLogs, runTwoStdOutLogs);
    distBuildLogStateTracker.processStreamLogs(streamLogsOne);
    assertLogLines(RUN_ONE_STD_ERR_LOG, ImmutableList.of("runOneStdErrLine1", "runOneStdErrLine2"));
    assertLogLines(RUN_TWO_STD_OUT_LOG, ImmutableList.of("runTwoStdOutLine1", "runTwoStdOutLine2", "runTwoStdOutLine3"));
    // New build status arrives.
    // runOne/stdErr has same values as last time (so fewer lines than already processed).
    // => ignore
    // runTwo/stdOut updated within existing batch 2
    // => fetch batch 2 and process new lines
    runTwoSlaveInfo.setStdOutCurrentBatchNumber(2);
    runTwoSlaveInfo.setStdOutCurrentBatchLineCount(3);
    buildSlaveInfos = ImmutableList.of(runOneSlaveInfo, runTwoSlaveInfo);
    List<LogLineBatchRequest> requestsTwo = distBuildLogStateTracker.createRealtimeLogRequests(buildSlaveInfos);
    assertThat(requestsTwo.size(), Matchers.equalTo(1));
    // Request runTwo/stdOut from batch 2
    assertTrue(requestsTwo.stream().anyMatch(r -> r.slaveStream.runId.equals(runTwoId) && r.slaveStream.streamType.equals(LogStreamType.STDOUT) && r.batchNumber == 2));
    // Process new logs
    runTwoStdOutLogs = new StreamLogs();
    runTwoStdOutLogs.setSlaveStream(runTwoStdOutStream);
    runTwoStdOutLogsBatchTwo = new LogLineBatch();
    runTwoStdOutLogsBatchTwo.setBatchNumber(2);
    runTwoStdOutLogsBatchTwo.setLines(ImmutableList.of("runTwoStdOutLine2\n", "runTwoStdOutLine3\n", "runTwoStdOutLine4\n"));
    runTwoStdOutLogs.setLogLineBatches(ImmutableList.of(runTwoStdOutLogsBatchTwo));
    List<StreamLogs> streamLogsTwo = ImmutableList.of(runTwoStdOutLogs);
    distBuildLogStateTracker.processStreamLogs(streamLogsTwo);
    assertLogLines(RUN_TWO_STD_OUT_LOG, ImmutableList.of("runTwoStdOutLine1", "runTwoStdOutLine2", "runTwoStdOutLine3", "runTwoStdOutLine4"));
    // New build status arrives.
    // runOne/stdOut has now been populated with 2 batches
    // runOne/stdErr updated to new batch 2, with changes to batch 1 too
    // => fetch 1 and 2, processing new lines in batch 1 and all lines in batch 2.
    // runTwo/stdOut updated to new batch 3, no changes to existing batches
    // => fetch batch 2 and 3, processing only changes in batch 3
    runOneSlaveInfo.setStdOutCurrentBatchNumber(2);
    runOneSlaveInfo.setStdOutCurrentBatchLineCount(2);
    runOneSlaveInfo.setStdErrCurrentBatchNumber(2);
    runOneSlaveInfo.setStdErrCurrentBatchLineCount(1);
    runTwoSlaveInfo.setStdOutCurrentBatchNumber(3);
    runTwoSlaveInfo.setStdOutCurrentBatchLineCount(2);
    // runOne has stdErr, and runTwo has stdOut to download.
    buildSlaveInfos = ImmutableList.of(runOneSlaveInfo, runTwoSlaveInfo);
    List<LogLineBatchRequest> requestsThree = distBuildLogStateTracker.createRealtimeLogRequests(buildSlaveInfos);
    assertThat(requestsThree.size(), Matchers.equalTo(3));
    // Request runOne/stdErr from batch 1
    assertTrue(requestsThree.stream().anyMatch(r -> r.slaveStream.runId.equals(runOneId) && r.slaveStream.streamType.equals(LogStreamType.STDERR) && r.batchNumber == 1));
    // Request runOne/stdOut from batch 1
    assertTrue(requestsThree.stream().anyMatch(r -> r.slaveStream.runId.equals(runOneId) && r.slaveStream.streamType.equals(LogStreamType.STDOUT) && r.batchNumber == 1));
    // Request runTwo/stdOut from batch 2
    assertTrue(requestsThree.stream().anyMatch(r -> r.slaveStream.runId.equals(runTwoId) && r.slaveStream.streamType.equals(LogStreamType.STDOUT) && r.batchNumber == 2));
    // Process new logs
    // runOne/stdErr
    runOneStdErrLogs = new StreamLogs();
    runOneStdErrLogs.setSlaveStream(runOneStdErrStream);
    runOneStdErrLogsBatchOne = new LogLineBatch();
    runOneStdErrLogsBatchOne.setBatchNumber(1);
    runOneStdErrLogsBatchOne.setLines(ImmutableList.of("runOneStdErrLine1\n", "runOneStdErrLine2\n", "runOneStdErrLine3\n"));
    LogLineBatch runOneStdErrLogsBatchTwo = new LogLineBatch();
    runOneStdErrLogsBatchTwo.setBatchNumber(2);
    runOneStdErrLogsBatchTwo.setLines(ImmutableList.of("runOneStdErrLine4\n"));
    runOneStdErrLogs.setLogLineBatches(ImmutableList.of(runOneStdErrLogsBatchOne, runOneStdErrLogsBatchTwo));
    // runOne/stdOut
    StreamLogs runOneStdOutLogs = new StreamLogs();
    runOneStdOutLogs.setSlaveStream(runOneStdOutStream);
    LogLineBatch runOneStdOutLogsBatchOne = new LogLineBatch();
    runOneStdOutLogsBatchOne.setBatchNumber(1);
    runOneStdOutLogsBatchOne.setLines(ImmutableList.of("runOneStdOutLine1\n", "runOneStdOutLine2\n"));
    LogLineBatch runOneStdOutLogsBatchTwo = new LogLineBatch();
    runOneStdOutLogsBatchTwo.setBatchNumber(2);
    runOneStdOutLogsBatchTwo.setLines(ImmutableList.of("runOneStdOutLine3\n", "runOneStdOutLine4\n"));
    runOneStdOutLogs.setLogLineBatches(ImmutableList.of(runOneStdOutLogsBatchOne, runOneStdOutLogsBatchTwo));
    // runTwo/stdOut
    runTwoStdOutLogs = new StreamLogs();
    runTwoStdOutLogs.setSlaveStream(runTwoStdOutStream);
    runTwoStdOutLogsBatchTwo = new LogLineBatch();
    runTwoStdOutLogsBatchTwo.setBatchNumber(2);
    runTwoStdOutLogsBatchTwo.setLines(ImmutableList.of("runTwoStdOutLine2\n", "runTwoStdOutLine3\n", "runTwoStdOutLine4\n"));
    LogLineBatch runTwoStdOutLogsBatchThree = new LogLineBatch();
    runTwoStdOutLogsBatchThree.setBatchNumber(3);
    runTwoStdOutLogsBatchThree.setLines(ImmutableList.of("runTwoStdOutLine5\n", "runTwoStdOutLine6\n"));
    runTwoStdOutLogs.setLogLineBatches(ImmutableList.of(runTwoStdOutLogsBatchTwo, runTwoStdOutLogsBatchThree));
    List<StreamLogs> streamLogsThree = ImmutableList.of(runOneStdErrLogs, runOneStdOutLogs, runTwoStdOutLogs);
    distBuildLogStateTracker.processStreamLogs(streamLogsThree);
    assertLogLines(RUN_ONE_STD_OUT_LOG, ImmutableList.of("runOneStdOutLine1", "runOneStdOutLine2", "runOneStdOutLine3", "runOneStdOutLine4"));
    assertLogLines(RUN_ONE_STD_ERR_LOG, ImmutableList.of("runOneStdErrLine1", "runOneStdErrLine2", "runOneStdErrLine3", "runOneStdErrLine4"));
    assertLogLines(RUN_TWO_STD_OUT_LOG, ImmutableList.of("runTwoStdOutLine1", "runTwoStdOutLine2", "runTwoStdOutLine3", "runTwoStdOutLine4", "runTwoStdOutLine5", "runTwoStdOutLine6"));
}
Also used : LogLineBatchRequest(com.facebook.buck.distributed.thrift.LogLineBatchRequest) LogLineBatch(com.facebook.buck.distributed.thrift.LogLineBatch) LogStreamType(com.facebook.buck.distributed.thrift.LogStreamType) TestDataHelper(com.facebook.buck.testutil.integration.TestDataHelper) StreamLogs(com.facebook.buck.distributed.thrift.StreamLogs) Assert.assertThat(org.junit.Assert.assertThat) ProjectFilesystem(com.facebook.buck.io.ProjectFilesystem) ImmutableList(com.google.common.collect.ImmutableList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LogLineBatchRequest(com.facebook.buck.distributed.thrift.LogLineBatchRequest) Path(java.nio.file.Path) Before(org.junit.Before) RunId(com.facebook.buck.distributed.thrift.RunId) LogDir(com.facebook.buck.distributed.thrift.LogDir) Files(java.nio.file.Files) Platform(com.facebook.buck.util.environment.Platform) Assert.assertTrue(org.junit.Assert.assertTrue) Matchers(org.hamcrest.Matchers) Test(org.junit.Test) IOException(java.io.IOException) BuildSlaveInfo(com.facebook.buck.distributed.thrift.BuildSlaveInfo) SlaveStream(com.facebook.buck.distributed.thrift.SlaveStream) List(java.util.List) Rule(org.junit.Rule) Stream(java.util.stream.Stream) Assume.assumeTrue(org.junit.Assume.assumeTrue) TemporaryFolder(org.junit.rules.TemporaryFolder) LogLineBatch(com.facebook.buck.distributed.thrift.LogLineBatch) BuildSlaveInfo(com.facebook.buck.distributed.thrift.BuildSlaveInfo) StreamLogs(com.facebook.buck.distributed.thrift.StreamLogs) RunId(com.facebook.buck.distributed.thrift.RunId) SlaveStream(com.facebook.buck.distributed.thrift.SlaveStream) Test(org.junit.Test)

Aggregations

LogLineBatch (com.facebook.buck.distributed.thrift.LogLineBatch)2 BuildSlaveInfo (com.facebook.buck.distributed.thrift.BuildSlaveInfo)1 LogDir (com.facebook.buck.distributed.thrift.LogDir)1 LogLineBatchRequest (com.facebook.buck.distributed.thrift.LogLineBatchRequest)1 LogStreamType (com.facebook.buck.distributed.thrift.LogStreamType)1 RunId (com.facebook.buck.distributed.thrift.RunId)1 SlaveStream (com.facebook.buck.distributed.thrift.SlaveStream)1 StreamLogs (com.facebook.buck.distributed.thrift.StreamLogs)1 ProjectFilesystem (com.facebook.buck.io.ProjectFilesystem)1 TestDataHelper (com.facebook.buck.testutil.integration.TestDataHelper)1 Platform (com.facebook.buck.util.environment.Platform)1 ImmutableList (com.google.common.collect.ImmutableList)1 IOException (java.io.IOException)1 Files (java.nio.file.Files)1 Path (java.nio.file.Path)1 List (java.util.List)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Stream (java.util.stream.Stream)1 Matchers (org.hamcrest.Matchers)1 Assert.assertThat (org.junit.Assert.assertThat)1