blob: b2ab883623a1d4f928f7bc34fda5d4f43433c236 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.jackrabbit.oak.segment.tool.iotrace;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.Writer;
import java.util.List;
import java.util.function.Function;
import org.apache.jackrabbit.oak.segment.file.FileStore;
import org.apache.jackrabbit.oak.segment.spi.monitor.IOMonitor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* This utility class allows collecting IO traces of read accesses to segments
* caused by reading specific items.
* <p>
* An instance of {@link Trace} is used to specify a read pattern. Segment reads
* are recorded in CSV format:
<pre>
timestamp,file,segmentId,length,elapsed
1522147945084,data01415a.tar,f81378df-b3f8-4b25-0000-00000002c450,181328,171849
1522147945096,data01415a.tar,f81378df-b3f8-4b25-0000-00000002c450,181328,131272
1522147945097,data01415a.tar,f81378df-b3f8-4b25-0000-00000002c450,181328,142766
...
</pre>
* {@link Trace} implementations can specify an additional context, which is recorded
* with each line of the CSV output. A context is simply a list of additional fields
* as specified during instantiation of an {@code IOTracer}.
*/
public class IOTracer {
@NotNull
private final Function<IOMonitor, FileStore> fileStoreFactory;
@NotNull
private final IOTraceMonitor ioMonitor;
private IOTracer(
@NotNull Function<IOMonitor, FileStore> fileStoreFactory,
@NotNull Writer output,
@Nullable String contextSpec) {
this.fileStoreFactory = checkNotNull(fileStoreFactory);
ioMonitor = new IOTraceMonitor(new DefaultIOTraceWriter(output), contextSpec);
}
/**
* Create a new {@code IOTracer} instance.
* @param fileStoreFactory A factory for creating a {@link FileStore} with the
* passed {@link IOMonitor} for monitoring segment IO.
* @param output The target for the CSV formatted IO trace.
* @param contextSpec The specification of additional context provided by
* the {@link Trace traces} being {@link IOTracer#collectTrace(Trace) run}.
* A trace consists of a comma separated list of values, which must match
* the list of values passed to {@link IOTracer#setContext(List)}.
* @return A new {@code IOTracer} instance.
*/
@NotNull
public static IOTracer newIOTracer(
@NotNull Function<IOMonitor, FileStore> fileStoreFactory,
@NotNull Writer output,
@Nullable String contextSpec) {
return new IOTracer(fileStoreFactory, output, contextSpec);
}
/**
* Collect a IO trace.
* @param trace
*/
public void collectTrace(@NotNull Trace trace) {
checkNotNull(trace);
try (FileStore fileStore = checkNotNull(fileStoreFactory).apply(checkNotNull(ioMonitor))) {
trace.run(fileStore.getHead());
} finally {
ioMonitor.flush();
}
}
/**
* Set the {@code context} to be added to each line of the IOTrace going forward. The list
* of values needs to match the context specification passed to
* {@link IOTracer#newIOTracer(Function, Writer, String)}.
* @param context
*/
public void setContext(@NotNull List<String> context) {
ioMonitor.setContext(context);
}
}