Rework the formatter a bit and extract out the writing logic so that it could be pluggable.

This commit is contained in:
A.J. Beamon 2018-05-31 13:27:35 -07:00
parent f7735d000f
commit f1dea3bed9
10 changed files with 751 additions and 558 deletions

187
flow/FileTraceLogWriter.cpp Normal file
View File

@ -0,0 +1,187 @@
/*
* FileTraceLogWriter.cpp
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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.
*/
#include "FileTraceLogWriter.h"
#include "flow.h"
#include "ThreadHelper.actor.h"
#if defined(__unixish__)
#define __open ::open
#define __write ::write
#define __close ::close
#define __fsync ::fsync
#define TRACEFILE_FLAGS O_WRONLY | O_CREAT | O_EXCL
#define TRACEFILE_MODE 0664
#elif defined(_WIN32)
#include <windows.h>
#undef max
#undef min
#include <io.h>
#include <stdio.h>
#include <sys/stat.h>
#define __open _open
#define __write _write
#define __close _close
#define __fsync _commit
#define TRACEFILE_FLAGS _O_WRONLY | _O_CREAT | _O_EXCL
#define TRACEFILE_MODE _S_IWRITE
#endif
#include <fcntl.h>
FileTraceLogWriter::FileTraceLogWriter(std::string directory, std::string processName, std::string basename, std::string extension, uint64_t maxLogsSize, std::function<void()> onError)
: directory(directory), processName(processName), basename(basename), extension(extension), maxLogsSize(maxLogsSize), traceFileFD(0), index(0), onError(onError) {}
void FileTraceLogWriter::addref() {
ReferenceCounted<FileTraceLogWriter>::addref();
}
void FileTraceLogWriter::delref() {
ReferenceCounted<FileTraceLogWriter>::delref();
}
void FileTraceLogWriter::lastError(int err) {
// Whenever we get a serious error writing a trace log, all flush barriers posted between the operation encountering
// the error and the occurrence of the error are unblocked, even though we haven't actually succeeded in flushing.
// Otherwise a permanent write error would make the program block forever.
if (err != 0 && err != EINTR) {
onError();
}
}
void FileTraceLogWriter::write(const std::string& str) {
auto ptr = str.c_str();
int remaining = str.size();
while ( remaining ) {
int ret = __write( traceFileFD, ptr, remaining );
if ( ret > 0 ) {
lastError(0);
remaining -= ret;
ptr += ret;
} else {
lastError(errno);
threadSleep(0.1);
}
}
}
void FileTraceLogWriter::open() {
cleanupTraceFiles();
auto finalname = format("%s.%d.%s", basename.c_str(), ++index, extension.c_str());
while ( (traceFileFD = __open( finalname.c_str(), TRACEFILE_FLAGS, TRACEFILE_MODE )) == -1 ) {
lastError(errno);
if (errno == EEXIST)
finalname = format("%s.%d.%s", basename.c_str(), ++index, extension.c_str());
else {
fprintf(stderr, "ERROR: could not create trace log file `%s' (%d: %s)\n", finalname.c_str(), errno, strerror(errno));
int errorNum = errno;
onMainThreadVoid([finalname, errorNum]{
TraceEvent(SevWarnAlways, "TraceFileOpenError")
.detail("Filename", finalname)
.detail("ErrorCode", errorNum)
.detail("Error", strerror(errorNum))
.trackLatest("TraceFileOpenError"); }, NULL);
threadSleep(FLOW_KNOBS->TRACE_RETRY_OPEN_INTERVAL);
}
}
onMainThreadVoid([]{ latestEventCache.clear("TraceFileOpenError"); }, NULL);
lastError(0);
}
void FileTraceLogWriter::close() {
if (traceFileFD) {
while ( __close(traceFileFD) ) threadSleep(0.1);
}
}
void FileTraceLogWriter::roll() {
close();
open();
}
void FileTraceLogWriter::sync() {
__fsync(traceFileFD);
}
void FileTraceLogWriter::extractTraceFileNameInfo(std::string const& filename, std::string &root, int &index) {
int split = filename.find_last_of('.', filename.size() - 5);
root = filename.substr(0, split);
if(sscanf(filename.substr(split + 1, filename.size() - split - 4).c_str(), "%d", &index) == EOF) {
index = -1;
}
}
bool FileTraceLogWriter::compareTraceFileName (std::string const& f1, std::string const& f2) {
std::string root1;
std::string root2;
int index1;
int index2;
extractTraceFileNameInfo(f1, root1, index1);
extractTraceFileNameInfo(f2, root2, index2);
if(root1 != root2)
return root1 < root2;
if(index1 != index2)
return index1 < index2;
return f1 < f2;
}
bool FileTraceLogWriter::reverseCompareTraceFileName(std::string f1, std::string f2) {
return compareTraceFileName(f2, f1);
}
void FileTraceLogWriter::cleanupTraceFiles() {
// Setting maxLogsSize=0 disables trace file cleanup based on dir size
if(!g_network->isSimulated() && maxLogsSize > 0) {
try {
std::vector<std::string> existingFiles = platform::listFiles(directory, extension);
std::vector<std::string> existingTraceFiles;
for(auto f = existingFiles.begin(); f != existingFiles.end(); ++f) {
if(f->substr(0, processName.length()) == processName) {
existingTraceFiles.push_back(*f);
}
}
// reverse sort, so we preserve the most recent files and delete the oldest
std::sort(existingTraceFiles.begin(), existingTraceFiles.end(), FileTraceLogWriter::reverseCompareTraceFileName);
int64_t runningTotal = 0;
std::vector<std::string>::iterator fileListIterator = existingTraceFiles.begin();
while(runningTotal < maxLogsSize && fileListIterator != existingTraceFiles.end()) {
runningTotal += (fileSize(joinPath(directory, *fileListIterator)) + FLOW_KNOBS->ZERO_LENGTH_FILE_PAD);
++fileListIterator;
}
while(fileListIterator != existingTraceFiles.end()) {
deleteFile(joinPath(directory, *fileListIterator));
++fileListIterator;
}
} catch( Error & ) {}
}
}

63
flow/FileTraceLogWriter.h Normal file
View File

@ -0,0 +1,63 @@
/*
* FileTraceLogWriter.h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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.
*/
#ifndef FLOW_FILE_TRACE_LOG_WRITER_H
#define FLOW_FILE_TRACE_LOG_WRITER_H
#pragma once
#include "FastRef.h"
#include "Trace.h"
class FileTraceLogWriter : public TraceLogWriter, ReferenceCounted<FileTraceLogWriter> {
private:
std::string directory;
std::string processName;
std::string basename;
std::string extension;
uint64_t maxLogsSize;
int traceFileFD;
int index;
std::function<void()> onError;
public:
FileTraceLogWriter(std::string directory, std::string processName, std::string basename, std::string extension, uint64_t maxLogsSize, std::function<void()> onError);
void addref();
void delref();
void lastError(int err);
void write(const std::string& str);
void open();
void close();
void roll();
void sync();
static void extractTraceFileNameInfo(std::string const& filename, std::string &root, int &index);
static bool compareTraceFileName (std::string const& f1, std::string const& f2);
static bool reverseCompareTraceFileName(std::string f1, std::string f2);
void cleanupTraceFiles();
};
#endif

View File

@ -115,7 +115,7 @@ FlowKnobs::FlowKnobs(bool randomize, bool isSimulated) {
init( TRACE_RETRY_OPEN_INTERVAL, 1.00 );
init( MIN_TRACE_SEVERITY, isSimulated ? 0 : 10 ); // Related to the trace severity in Trace.h
init( MAX_TRACE_SUPPRESSIONS, 1e4 );
init( TRACE_FSYNC_ENABLED, 0 );
init( TRACE_SYNC_ENABLED, 0 );
init( TRACE_EVENT_METRIC_UNITS_PER_SAMPLE, 500 );
init( TRACE_EVENT_THROTLLER_SAMPLE_EXPIRY, 1800.0 ); // 30 mins
init( TRACE_EVENT_THROTTLER_MSG_LIMIT, 20000 );

View File

@ -137,7 +137,7 @@ public:
double TRACE_RETRY_OPEN_INTERVAL;
int MIN_TRACE_SEVERITY;
int MAX_TRACE_SUPPRESSIONS;
int TRACE_FSYNC_ENABLED;
int TRACE_SYNC_ENABLED;
int TRACE_EVENT_METRIC_UNITS_PER_SAMPLE;
int TRACE_EVENT_THROTLLER_SAMPLE_EXPIRY;
int TRACE_EVENT_THROTTLER_MSG_LIMIT;

View File

@ -20,15 +20,12 @@
#include "Trace.h"
#include "FileTraceLogWriter.h"
#include "XmlTraceLogFormatter.h"
#include "flow.h"
#include "DeterministicRandom.h"
#include <stdlib.h>
#include <stdarg.h>
#ifdef WIN32
#include <windows.h>
#undef max
#undef min
#endif
#include <time.h>
#include "IThreadPool.h"
@ -38,26 +35,6 @@
#include "TDMetric.actor.h"
#include "MetricSample.h"
#include <fcntl.h>
#if defined(__unixish__)
#define __open ::open
#define __write ::write
#define __close ::close
#define __fsync ::fsync
#define TRACEFILE_FLAGS O_WRONLY | O_CREAT | O_EXCL
#define TRACEFILE_MODE 0664
#elif defined(_WIN32)
#include <io.h>
#include <stdio.h>
#include <sys/stat.h>
#define __open _open
#define __write _write
#define __close _close
#define __fsync _commit
#define TRACEFILE_FLAGS _O_WRONLY | _O_CREAT | _O_EXCL
#define TRACEFILE_MODE _S_IWRITE
#endif
class DummyThreadPool : public IThreadPool, ReferenceCounted<DummyThreadPool> {
public:
~DummyThreadPool() {}
@ -136,91 +113,14 @@ SuppressionMap suppressedEvents;
static TransientThresholdMetricSample<Standalone<StringRef>> *traceEventThrottlerCache;
static const char *TRACE_EVENT_THROTTLE_STARTING_TYPE = "TraceEventThrottle_";
struct XmlTraceLogFormatter : public TraceLogFormatter, ReferenceCounted<XmlTraceLogFormatter> {
void addref() {
ReferenceCounted<XmlTraceLogFormatter>::addref();
}
void delref() {
ReferenceCounted<XmlTraceLogFormatter>::delref();
}
const char* getExtension() {
return "xml";
}
const char* getHeader() {
return "<?xml version=\"1.0\"?>\r\n<Trace>\r\n";
}
const char* getFooter() {
return "</Trace>\r\n";
}
std::string escape(std::string source) {
std::string result;
int offset = 0;
loop {
int index = source.find_first_of(std::string({'&', '"', '<', '>', '\r', '\n', '\0'}), offset);
if(index == source.npos) {
break;
}
result += source.substr(offset, index-offset);
if(source[index] == '&') {
result += "&amp;";
}
else if(source[index] == '"') {
result += "&quot;";
}
else if(source[index] == '<') {
result += "&lt;";
}
else if(source[index] == '>') {
result += "&gt;";
}
else if(source[index] == '\n' || source[index] == '\r') {
result += " ";
}
else if(source[index] == '\0') {
result += " ";
TraceEvent(SevWarnAlways, "StrippedIllegalCharacterFromTraceEvent").detail("Source", StringRef(source).printable()).detail("Character", StringRef(source.substr(index, 1)).printable());
}
else {
ASSERT(false);
}
offset = index+1;
}
if(offset == 0) {
return source;
}
else {
result += source.substr(offset);
return result;
}
}
std::string formatEvent(const TraceEventFields &fields) {
std::string event = "<Event ";
for(auto itr : fields) {
event += escape(itr.first) + "=\"" + escape(itr.second) + "\" ";
}
event += "/>\r\n";
return event;
}
};
struct TraceLog {
private:
Reference<TraceLogWriter> logWriter;
Reference<TraceLogFormatter> formatter;
Standalone< VectorRef<StringRef> > buffer;
int file_length;
int buffer_length;
std::vector<TraceEventFields> eventBuffer;
int loggedLength;
int bufferLength;
bool opened;
int64_t preopenOverflowCount;
std::string basename;
@ -285,98 +185,38 @@ public:
Reference<BarrierList> barriers;
struct WriterThread : IThreadPoolReceiver {
WriterThread( std::string directory, std::string processName, uint32_t maxLogsSize, std::string basename, std::string logGroup, Optional<NetworkAddress> localAddress, Reference<BarrierList> barriers, Reference<TraceLogFormatter> formatter )
: directory(directory), processName(processName), maxLogsSize(maxLogsSize), basename(basename), logGroup(logGroup), localAddress(localAddress), traceFileFD(0), index(0), barriers(barriers), formatter(formatter) {}
WriterThread( Reference<BarrierList> barriers, Reference<TraceLogWriter> logWriter, Reference<TraceLogFormatter> formatter )
: barriers(barriers), logWriter(logWriter), formatter(formatter) {}
virtual void init() {}
Reference<TraceLogWriter> logWriter;
Reference<TraceLogFormatter> formatter;
Reference<BarrierList> barriers;
int traceFileFD;
std::string directory;
std::string processName;
int maxLogsSize;
std::string basename;
std::string logGroup;
Optional<NetworkAddress> localAddress;
int index;
void lastError(int err) {
// Whenever we get a serious error writing a trace log, all flush barriers posted between the operation encountering
// the error and the occurrence of the error are unblocked, even though we haven't actually succeeded in flushing.
// Otherwise a permanent write error would make the program block forever.
if (err != 0 && err != EINTR) {
barriers->triggerAll();
}
}
void writeReliable(const uint8_t* buf, int count) {
auto ptr = buf;
int remaining = count;
while ( remaining ) {
int ret = __write( traceFileFD, ptr, remaining );
if ( ret > 0 ) {
lastError(0);
remaining -= ret;
ptr += ret;
} else {
lastError(errno);
threadSleep(0.1);
}
}
}
void writeReliable(const char* msg) {
writeReliable( (const uint8_t*)msg, strlen(msg) );
}
void handleTraceFileOpenError(const std::string& filename)
{
}
struct Open : TypedAction<WriterThread,Open> {
virtual double getTimeEstimate() { return 0; }
};
void action( Open& o ) {
close();
cleanupTraceFiles();
auto finalname = format("%s.%d.%s", basename.c_str(), ++index, formatter->getExtension());
while ( (traceFileFD = __open( finalname.c_str(), TRACEFILE_FLAGS, TRACEFILE_MODE )) == -1 ) {
lastError(errno);
if (errno == EEXIST)
finalname = format("%s.%d.%s", basename.c_str(), ++index, formatter->getExtension());
else {
fprintf(stderr, "ERROR: could not create trace log file `%s' (%d: %s)\n", finalname.c_str(), errno, strerror(errno));
int errorNum = errno;
onMainThreadVoid([finalname, errorNum]{
TraceEvent(SevWarnAlways, "TraceFileOpenError")
.detail("Filename", finalname)
.detail("ErrorCode", errorNum)
.detail("Error", strerror(errorNum))
.trackLatest("TraceFileOpenError"); }, NULL);
threadSleep(FLOW_KNOBS->TRACE_RETRY_OPEN_INTERVAL);
}
}
onMainThreadVoid([]{ latestEventCache.clear("TraceFileOpenError"); }, NULL);
lastError(0);
writeReliable(formatter->getHeader());
logWriter->open();
logWriter->write(formatter->getHeader());
}
struct Close : TypedAction<WriterThread,Close> {
virtual double getTimeEstimate() { return 0; }
};
void action( Close& c ) {
close();
logWriter->write(formatter->getFooter());
logWriter->close();
}
void close() {
if (traceFileFD) {
writeReliable(formatter->getFooter());
while ( __close(traceFileFD) ) threadSleep(0.1);
}
struct Roll : TypedAction<WriterThread,Roll> {
virtual double getTimeEstimate() { return 0; }
};
void action( Roll& c ) {
logWriter->write(formatter->getFooter());
logWriter->roll();
logWriter->write(formatter->getHeader());
}
struct Barrier : TypedAction<WriterThread, Barrier> {
@ -387,57 +227,23 @@ public:
}
struct WriteBuffer : TypedAction<WriterThread, WriteBuffer> {
Standalone< VectorRef<StringRef> > buffer;
std::vector<TraceEventFields> events;
WriteBuffer( Standalone< VectorRef<StringRef> > buffer ) : buffer(buffer) {}
WriteBuffer(std::vector<TraceEventFields> events) : events(events) {}
virtual double getTimeEstimate() { return .001; }
};
void action( WriteBuffer& a ) {
if ( traceFileFD ) {
for ( auto i = a.buffer.begin(); i != a.buffer.end(); ++i ) {
writeReliable(i->begin(), i->size());
}
if(FLOW_KNOBS->TRACE_FSYNC_ENABLED) {
__fsync( traceFileFD );
}
a.buffer = Standalone< VectorRef<StringRef> >();
for(auto event : a.events) {
logWriter->write(formatter->formatEvent(event));
}
}
void cleanupTraceFiles() {
// Setting maxLogsSize=0 disables trace file cleanup based on dir size
if(!g_network->isSimulated() && maxLogsSize > 0) {
try {
std::vector<std::string> existingFiles = platform::listFiles(directory, ".xml");
std::vector<std::string> existingTraceFiles;
for(auto f = existingFiles.begin(); f != existingFiles.end(); ++f)
if(f->substr(0, processName.length()) == processName)
existingTraceFiles.push_back(*f);
// reverse sort, so we preserve the most recent files and delete the oldest
std::sort(existingTraceFiles.begin(), existingTraceFiles.end(), TraceLog::reverseCompareTraceFileName);
int64_t runningTotal = 0;
std::vector<std::string>::iterator fileListIterator = existingTraceFiles.begin();
while(runningTotal < maxLogsSize && fileListIterator != existingTraceFiles.end()) {
runningTotal += (fileSize(joinPath(directory, *fileListIterator)) + FLOW_KNOBS->ZERO_LENGTH_FILE_PAD);
++fileListIterator;
}
while(fileListIterator != existingTraceFiles.end()) {
deleteFile(joinPath(directory, *fileListIterator));
++fileListIterator;
}
} catch( Error & ) {}
if(FLOW_KNOBS->TRACE_SYNC_ENABLED) {
logWriter->sync();
}
}
};
TraceLog() : buffer_length(0), file_length(0), opened(false), preopenOverflowCount(0), barriers(new BarrierList), logTraceEventMetrics(false), formatter(new XmlTraceLogFormatter()) {}
TraceLog() : bufferLength(0), loggedLength(0), opened(false), preopenOverflowCount(0), barriers(new BarrierList), logTraceEventMetrics(false), formatter(new XmlTraceLogFormatter()) {}
bool isOpen() const { return opened; }
@ -449,12 +255,13 @@ public:
this->localAddress = na;
basename = format("%s/%s.%s.%s", directory.c_str(), processName.c_str(), timestamp.c_str(), g_random->randomAlphaNumeric(6).c_str());
logWriter = Reference<TraceLogWriter>(new FileTraceLogWriter(directory, processName, basename, formatter->getExtension(), maxLogsSize, [this](){ barriers->triggerAll(); }));
if ( g_network->isSimulated() )
writer = Reference<IThreadPool>(new DummyThreadPool());
else
writer = createGenericThreadPool();
writer->addThread( new WriterThread(directory, processName, maxLogsSize, basename, logGroup, localAddress, barriers, formatter) );
writer->addThread( new WriterThread(barriers, logWriter, formatter) );
rollsize = rs;
@ -470,7 +277,7 @@ public:
// 2. Simulated runs manually insert the Machine field at TraceEvent creation time. Real-world runs add this field at write time.
//
// Without the ability to resolve the ambiguity, we've chosen to always favor the real-world approach and not support such events in simulation.
buffer = Standalone<VectorRef<StringRef>>();
eventBuffer.clear();
}
opened = true;
@ -480,35 +287,6 @@ public:
}
}
static void extractTraceFileNameInfo(std::string const& filename, std::string &root, int &index) {
int split = filename.find_last_of('.', filename.size() - 5);
root = filename.substr(0, split);
if(sscanf(filename.substr(split + 1, filename.size() - split - 4).c_str(), "%d", &index) == EOF)
index = -1;
}
static bool compareTraceFileName (std::string const& f1, std::string const& f2) {
std::string root1;
std::string root2;
int index1;
int index2;
extractTraceFileNameInfo(f1, root1, index1);
extractTraceFileNameInfo(f2, root2, index2);
if(root1 != root2)
return root1 < root2;
if(index1 != index2)
return index1 < index2;
return f1 < f2;
}
static bool reverseCompareTraceFileName(std::string f1, std::string f2) {
return compareTraceFileName(f2, f1);
}
void writeEvent( TraceEventFields fields, std::string trackLatestKey, bool trackError ) {
if(localAddress.present()) {
fields.addField("Machine", format("%d.%d.%d.%d:%d", (localAddress.get().ip>>24)&0xff, (localAddress.get().ip>>16)&0xff, (localAddress.get().ip>>8)&0xff, localAddress.get().ip&0xff, localAddress.get().port));
@ -520,17 +298,15 @@ public:
fields.addField("TrackLatestType", "Original");
}
std::string eventStr = formatter->formatEvent(fields);
MutexHolder hold(mutex);
if(!isOpen() && (preopenOverflowCount > 0 || buffer_length + eventStr.size() > FLOW_KNOBS->TRACE_LOG_MAX_PREOPEN_BUFFER)) {
if(!isOpen() && (preopenOverflowCount > 0 || bufferLength + fields.sizeBytes() > FLOW_KNOBS->TRACE_LOG_MAX_PREOPEN_BUFFER)) {
++preopenOverflowCount;
return;
}
// FIXME: What if we are using way too much memory for buffer?
buffer.push_back_deep( buffer.arena(), StringRef((const uint8_t*)eventStr.c_str(), eventStr.size()) );
buffer_length += eventStr.size();
eventBuffer.push_back(fields);
bufferLength += fields.sizeBytes();
if(trackError) {
latestEventCache.setLatestError(fields);
@ -569,18 +345,21 @@ public:
MutexHolder hold(mutex);
bool roll = false;
if (!buffer.size()) return Void(); // SOMEDAY: maybe we still roll the tracefile here?
if (!eventBuffer.size()) return Void(); // SOMEDAY: maybe we still roll the tracefile here?
if (rollsize && buffer_length + file_length > rollsize) // SOMEDAY: more conditions to roll
if (rollsize && bufferLength + loggedLength > rollsize) // SOMEDAY: more conditions to roll
roll = true;
auto a = new WriterThread::WriteBuffer( std::move(buffer) );
file_length += buffer_length;
buffer = Standalone<VectorRef<StringRef>>();
buffer_length = 0;
auto a = new WriterThread::WriteBuffer( std::move(eventBuffer) );
loggedLength += bufferLength;
eventBuffer = std::vector<TraceEventFields>();
bufferLength = 0;
writer->post( a );
if (roll) {
auto o = new WriterThread::Roll;
writer->post(o);
std::vector<TraceEventFields> events = latestEventCache.getAllUnsafe();
for (int idx = 0; idx < events.size(); idx++) {
if(events[idx].size() > 0) {
@ -598,13 +377,11 @@ public:
}
}
buffer.push_back_deep( buffer.arena(), StringRef(formatter->formatEvent(rolledFields)) );
eventBuffer.push_back(rolledFields);
}
}
auto o = new WriterThread::Open;
file_length = 0;
writer->post( o );
loggedLength = 0;
}
ThreadFuture<Void> f(new ThreadSingleAssignmentVar<Void>);
@ -619,10 +396,10 @@ public:
MutexHolder hold(mutex);
// Write remaining contents
auto a = new WriterThread::WriteBuffer( std::move(buffer) );
file_length += buffer_length;
buffer = Standalone<VectorRef<StringRef>>();
buffer_length = 0;
auto a = new WriterThread::WriteBuffer( std::move(eventBuffer) );
loggedLength += bufferLength;
eventBuffer = std::vector<TraceEventFields>();
bufferLength = 0;
writer->post( a );
auto c = new WriterThread::Close();
@ -830,7 +607,6 @@ bool TraceEvent::init( Severity severity, const char* type ) {
this->severity = severity;
tmpEventMetric = new DynamicEventMetric(MetricNameRef());
length = 0;
if (isEnabled(type, severity)) {
enabled = true;
@ -886,9 +662,8 @@ TraceEvent& TraceEvent::detailImpl( std::string key, std::string value, bool wri
}
fields.addField(key, value);
length += key.size() + value.size();
if(length > FLOW_KNOBS->TRACE_EVENT_MAX_SIZE) {
if(fields.sizeBytes() > FLOW_KNOBS->TRACE_EVENT_MAX_SIZE) {
TraceEvent(SevError, "TraceEventOverflow").detail("TraceFirstBytes", fields.toString().substr(300));
enabled = false;
}
@ -1182,7 +957,10 @@ TraceBatch::BuggifyInfo::BuggifyInfo(double time, int activated, int line, std::
fields.addField("Line", format("%d", line));
}
TraceEventFields::TraceEventFields() : bytes(0) {}
void TraceEventFields::addField(std::string key, std::string value) {
bytes += key.size() + value.size();
fields.push_back(std::make_pair(key, value));
}
@ -1190,6 +968,10 @@ size_t TraceEventFields::size() const {
return fields.size();
}
size_t TraceEventFields::sizeBytes() const {
return bytes;
}
TraceEventFields::FieldIterator TraceEventFields::begin() const {
return fields.cbegin();
}

View File

@ -58,7 +58,10 @@ public:
typedef std::vector<Field> FieldContainer;
typedef FieldContainer::const_iterator FieldIterator;
TraceEventFields();
size_t size() const;
size_t sizeBytes() const;
FieldIterator begin() const;
FieldIterator end() const;
@ -72,6 +75,7 @@ public:
private:
FieldContainer fields;
size_t bytes;
};
template <class Archive>
@ -193,6 +197,17 @@ private:
bool init( Severity, struct TraceInterval& );
};
struct TraceLogWriter {
virtual void open() = 0;
virtual void roll() = 0;
virtual void close() = 0;
virtual void write(const std::string&) = 0;
virtual void sync() = 0;
virtual void addref() = 0;
virtual void delref() = 0;
};
struct TraceLogFormatter {
virtual const char* getExtension() = 0;
virtual const char* getHeader() = 0; // Called when starting a new file

View File

@ -0,0 +1,95 @@
/*
* XmlTraceLogFormatter.cpp
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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.
*/
#include "actorcompiler.h"
#include "XmlTraceLogFormatter.h"
void XmlTraceLogFormatter::addref() {
ReferenceCounted<XmlTraceLogFormatter>::addref();
}
void XmlTraceLogFormatter::delref() {
ReferenceCounted<XmlTraceLogFormatter>::delref();
}
const char* XmlTraceLogFormatter::getExtension() {
return "xml";
}
const char* XmlTraceLogFormatter::getHeader() {
return "<?xml version=\"1.0\"?>\r\n<Trace>\r\n";
}
const char* XmlTraceLogFormatter::getFooter() {
return "</Trace>\r\n";
}
void XmlTraceLogFormatter::escape(std::stringstream &ss, std::string source) {
loop {
int index = source.find_first_of(std::string({'&', '"', '<', '>', '\r', '\n', '\0'}));
if(index == source.npos) {
break;
}
ss << source.substr(0, index);
if(source[index] == '&') {
ss << "&amp;";
}
else if(source[index] == '"') {
ss << "&quot;";
}
else if(source[index] == '<') {
ss << "&lt;";
}
else if(source[index] == '>') {
ss << "&gt;";
}
else if(source[index] == '\n' || source[index] == '\r') {
ss << " ";
}
else if(source[index] == '\0') {
ss << " ";
TraceEvent(SevWarnAlways, "StrippedIllegalCharacterFromTraceEvent").detail("Source", StringRef(source).printable()).detail("Character", StringRef(source.substr(index, 1)).printable());
}
else {
ASSERT(false);
}
source = source.substr(index+1);
}
ss << source;
}
std::string XmlTraceLogFormatter::formatEvent(const TraceEventFields &fields) {
std::stringstream ss;
ss << "<Event ";
for(auto itr : fields) {
escape(ss, itr.first);
ss << "=\"";
escape(ss, itr.second);
ss << "\" ";
}
ss << "/>\r\n";
return ss.str();
}

View File

@ -0,0 +1,43 @@
/*
* XmlTraceLogFormatter.h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2018 Apple Inc. and the FoundationDB project authors
*
* Licensed 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.
*/
#ifndef FLOW_XML_TRACE_LOG_FORMATTER_H
#define FLOW_XML_TRACE_LOG_FORMATTER_H
#pragma once
#include <sstream>
#include "FastRef.h"
#include "Trace.h"
struct XmlTraceLogFormatter : public TraceLogFormatter, ReferenceCounted<XmlTraceLogFormatter> {
void addref();
void delref();
const char* getExtension();
const char* getHeader();
const char* getFooter();
void escape(std::stringstream &ss, std::string source);
std::string formatEvent(const TraceEventFields &fields);
};
#endif

View File

@ -1,203 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|X64">
<Configuration>Debug</Configuration>
<Platform>X64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|X64">
<Configuration>Release</Configuration>
<Platform>X64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ActorCompiler Include="ActorCollection.actor.cpp" />
<ActorCompiler Include="CompressedInt.actor.cpp" />
<ClCompile Include="boost.cpp" />
<ClCompile Include="Deque.cpp" />
<ClCompile Include="Error.cpp" />
<ClCompile Include="FastAlloc.cpp" />
<ClCompile Include="FaultInjection.cpp" />
<ClInclude Include="MetricSample.h" />
<ClInclude Include="Profiler.h" />
<ActorCompiler Include="Profiler.actor.cpp" />
<ActorCompiler Include="Net2.actor.cpp" />
<ClCompile Include="IThreadPool.cpp" />
<ClCompile Include="network.cpp" />
<ClCompile Include="flow.cpp" />
<ActorCompiler Include="genericactors.actor.cpp" />
<ClCompile Include="Hash3.c" />
<ClCompile Include="IndexedSet.cpp" />
<ClCompile Include="Knobs.cpp" />
<ClCompile Include="Net2Packet.cpp" />
<ActorCompiler Include="Stats.actor.cpp" />
<ClCompile Include="SystemMonitor.cpp" />
<ClCompile Include="TDMetric.cpp" />
<ClCompile Include="ThreadHelper.cpp" />
<ClCompile Include="ThreadPrimitives.cpp" />
<ClCompile Include="Platform.cpp" />
<ClCompile Include="stacktrace.amalgamation.cpp" />
<ClCompile Include="Trace.cpp" />
<ClCompile Include="UnitTest.cpp" />
<ClCompile Include="version.cpp" />
<ClCompile Include="SignalSafeUnwind.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CompressedInt.h" />
<ClInclude Include="ActorCollection.h" />
<ClInclude Include="actorcompiler.h" />
<ClInclude Include="Arena.h" />
<ClInclude Include="AsioReactor.h" />
<ClInclude Include="Deque.h" />
<ClInclude Include="DeterministicRandom.h" />
<ClInclude Include="Error.h" />
<ClInclude Include="error_definitions.h" />
<ClInclude Include="FastAlloc.h" />
<ClInclude Include="FastRef.h" />
<ClInclude Include="FaultInjection.h" />
<ClInclude Include="network.h" />
<ClInclude Include="flow.h" />
<ActorCompiler Include="EventTypes.actor.h">
<EnableCompile>false</EnableCompile>
<EnableCompile>false</EnableCompile>
</ActorCompiler>
<ActorCompiler Include="genericactors.actor.h">
<EnableCompile>false</EnableCompile>
</ActorCompiler>
<ClInclude Include="Hash3.h" />
<ActorCompiler Include="IndexedSet.actor.h">
<EnableCompile>false</EnableCompile>
</ActorCompiler>
<ClInclude Include="IDispatched.h" />
<ClInclude Include="IndexedSet.h" />
<ClInclude Include="IRandom.h" />
<ClInclude Include="IThreadPool.h" />
<ClInclude Include="Knobs.h" />
<ClInclude Include="Net2Packet.h" />
<ClInclude Include="serialize.h" />
<ClInclude Include="SimpleOpt.h" />
<ClInclude Include="stacktrace.h" />
<ClInclude Include="Stats.h" />
<ClInclude Include="SystemMonitor.h" />
<ClInclude Include="ThreadPrimitives.h" />
<ClInclude Include="Platform.h" />
<ClInclude Include="ThreadSafeQueue.h" />
<ClInclude Include="Trace.h" />
<ClInclude Include="SignalSafeUnwind.h" />
<ClInclude Include="UnitTest.h" />
<ActorCompiler Include="ThreadHelper.actor.h">
<EnableCompile>false</EnableCompile>
</ActorCompiler>
<ActorCompiler Include="TDMetric.actor.h">
<EnableCompile>false</EnableCompile>
</ActorCompiler>
</ItemGroup>
<ItemGroup>
<None Include="no_intellisense.opt" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGUID>{00AC9087-0378-4872-9992-DF267CF12ACB}</ProjectGUID>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<Keyword>Win32Proj</Keyword>
<RootNamespace>flow</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
<IntDir>$(SystemDrive)\temp\msvcfdb\$(Platform)$(Configuration)\$(MSBuildProjectName)\</IntDir>
<BuildLogFile>$(IntDir)\$(MSBuildProjectName).log</BuildLogFile>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath);../;C:\Program Files\boost_1_52_0</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath);../;C:\Program Files\boost_1_52_0</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup>
<PreBuildEvent>
<Command>echo const char *hgVersion = "Current version id not currently supported within Windows."; &gt; hgVersion.temp.h &amp;&amp; fc /b hgVersion.temp.h hgVersion.h &gt; nul || copy hgVersion.temp.h hgVersion.h &gt; nul</Command>
<Message>Checking HG source version</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>false</MinimalRebuild>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;WINVER=0x0502;NTDDI_VERSION=0x05020000;_DEBUG;_HAS_ITERATOR_DEBUGGING=0;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalOptions>/bigobj @../flow/no_intellisense.opt %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Advapi32.lib</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>psapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Full</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;WINVER=0x0502;NTDDI_VERSION=0x05020000;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;FDB_CLEAN_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<EnablePREfast>false</EnablePREfast>
<AdditionalOptions>/bigobj @../flow/no_intellisense.opt %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
<OptimizeReferences>false</OptimizeReferences>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<AdditionalDependencies>Advapi32.lib</AdditionalDependencies>
<AdditionalOptions>/LTCG %(AdditionalOptions)</AdditionalOptions>
</Link>
<Lib>
<AdditionalDependencies>psapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ImportGroup Label="ExtensionTargets">
<Import Project="actorcompiler\ActorCompiler.targets" />
</ImportGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="MyPreCompileSteps" AfterTargets="CLCompile">
<Exec Command="$(SolutionDir)bin\$(Configuration)\coveragetool.exe &quot;$(OutDir)coverage.$(TargetName).xml&quot; @(ActorCompiler -> '%(RelativeDir)%(Filename)%(Extension)', ' ') @(CLInclude -> '%(RelativeDir)%(Filename)%(Extension)', ' ') @(CLCompile -> '%(RelativeDir)%(Filename)%(Extension)', ' ')" />
</Target>
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|X64">
<Configuration>Debug</Configuration>
<Platform>X64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|X64">
<Configuration>Release</Configuration>
<Platform>X64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ActorCompiler Include="ActorCollection.actor.cpp" />
<ActorCompiler Include="CompressedInt.actor.cpp" />
<ClCompile Include="boost.cpp" />
<ClCompile Include="Deque.cpp" />
<ClCompile Include="Error.cpp" />
<ClCompile Include="FastAlloc.cpp" />
<ClCompile Include="FaultInjection.cpp" />
<ClCompile Include="FileTraceLogWriter.cpp" />
<ClCompile Include="XmlTraceLogFormatter.cpp" />
<ClInclude Include="FileTraceLogWriter.h" />
<ClInclude Include="XmlTraceLogFormatter.h" />
<ClInclude Include="MetricSample.h" />
<ClInclude Include="Profiler.h" />
<ActorCompiler Include="Profiler.actor.cpp" />
<ActorCompiler Include="Net2.actor.cpp" />
<ClCompile Include="IThreadPool.cpp" />
<ClCompile Include="network.cpp" />
<ClCompile Include="flow.cpp" />
<ActorCompiler Include="genericactors.actor.cpp" />
<ClCompile Include="Hash3.c" />
<ClCompile Include="IndexedSet.cpp" />
<ClCompile Include="Knobs.cpp" />
<ClCompile Include="Net2Packet.cpp" />
<ActorCompiler Include="Stats.actor.cpp" />
<ClCompile Include="SystemMonitor.cpp" />
<ClCompile Include="TDMetric.cpp" />
<ClCompile Include="ThreadHelper.cpp" />
<ClCompile Include="ThreadPrimitives.cpp" />
<ClCompile Include="Platform.cpp" />
<ClCompile Include="stacktrace.amalgamation.cpp" />
<ClCompile Include="Trace.cpp" />
<ClCompile Include="UnitTest.cpp" />
<ClCompile Include="version.cpp" />
<ClCompile Include="SignalSafeUnwind.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CompressedInt.h" />
<ClInclude Include="ActorCollection.h" />
<ClInclude Include="actorcompiler.h" />
<ClInclude Include="Arena.h" />
<ClInclude Include="AsioReactor.h" />
<ClInclude Include="Deque.h" />
<ClInclude Include="DeterministicRandom.h" />
<ClInclude Include="Error.h" />
<ClInclude Include="error_definitions.h" />
<ClInclude Include="FastAlloc.h" />
<ClInclude Include="FastRef.h" />
<ClInclude Include="FaultInjection.h" />
<ClInclude Include="network.h" />
<ClInclude Include="flow.h" />
<ActorCompiler Include="EventTypes.actor.h">
<EnableCompile>false</EnableCompile>
<EnableCompile>false</EnableCompile>
</ActorCompiler>
<ActorCompiler Include="genericactors.actor.h">
<EnableCompile>false</EnableCompile>
</ActorCompiler>
<ClInclude Include="Hash3.h" />
<ActorCompiler Include="IndexedSet.actor.h">
<EnableCompile>false</EnableCompile>
</ActorCompiler>
<ClInclude Include="IDispatched.h" />
<ClInclude Include="IndexedSet.h" />
<ClInclude Include="IRandom.h" />
<ClInclude Include="IThreadPool.h" />
<ClInclude Include="Knobs.h" />
<ClInclude Include="Net2Packet.h" />
<ClInclude Include="serialize.h" />
<ClInclude Include="SimpleOpt.h" />
<ClInclude Include="stacktrace.h" />
<ClInclude Include="Stats.h" />
<ClInclude Include="SystemMonitor.h" />
<ClInclude Include="ThreadPrimitives.h" />
<ClInclude Include="Platform.h" />
<ClInclude Include="ThreadSafeQueue.h" />
<ClInclude Include="Trace.h" />
<ClInclude Include="SignalSafeUnwind.h" />
<ClInclude Include="UnitTest.h" />
<ActorCompiler Include="ThreadHelper.actor.h">
<EnableCompile>false</EnableCompile>
</ActorCompiler>
<ActorCompiler Include="TDMetric.actor.h">
<EnableCompile>false</EnableCompile>
</ActorCompiler>
</ItemGroup>
<ItemGroup>
<None Include="no_intellisense.opt" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGUID>{00AC9087-0378-4872-9992-DF267CF12ACB}</ProjectGUID>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<Keyword>Win32Proj</Keyword>
<RootNamespace>flow</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
<IntDir>$(SystemDrive)\temp\msvcfdb\$(Platform)$(Configuration)\$(MSBuildProjectName)\</IntDir>
<BuildLogFile>$(IntDir)\$(MSBuildProjectName).log</BuildLogFile>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath);../;C:\Program Files\boost_1_52_0</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath);../;C:\Program Files\boost_1_52_0</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup>
<PreBuildEvent>
<Command>echo const char *hgVersion = "Current version id not currently supported within Windows."; &gt; hgVersion.temp.h &amp;&amp; fc /b hgVersion.temp.h hgVersion.h &gt; nul || copy hgVersion.temp.h hgVersion.h &gt; nul</Command>
<Message>Checking HG source version</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|X64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>false</MinimalRebuild>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;WINVER=0x0502;NTDDI_VERSION=0x05020000;_DEBUG;_HAS_ITERATOR_DEBUGGING=0;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalOptions>/bigobj @../flow/no_intellisense.opt %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Advapi32.lib</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>psapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|X64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Full</Optimization>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;WINVER=0x0502;NTDDI_VERSION=0x05020000;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;FDB_CLEAN_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<EnablePREfast>false</EnablePREfast>
<AdditionalOptions>/bigobj @../flow/no_intellisense.opt %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
<OptimizeReferences>false</OptimizeReferences>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<AdditionalDependencies>Advapi32.lib</AdditionalDependencies>
<AdditionalOptions>/LTCG %(AdditionalOptions)</AdditionalOptions>
</Link>
<Lib>
<AdditionalDependencies>psapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ImportGroup Label="ExtensionTargets">
<Import Project="actorcompiler\ActorCompiler.targets" />
</ImportGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="MyPreCompileSteps" AfterTargets="CLCompile">
<Exec Command="$(SolutionDir)bin\$(Configuration)\coveragetool.exe &quot;$(OutDir)coverage.$(TargetName).xml&quot; @(ActorCompiler -> '%(RelativeDir)%(Filename)%(Extension)', ' ') @(CLInclude -> '%(RelativeDir)%(Filename)%(Extension)', ' ') @(CLCompile -> '%(RelativeDir)%(Filename)%(Extension)', ' ')" />
</Target>
</Project>

View File

@ -1,79 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ActorCompiler Include="ActorCollection.actor.cpp" />
<ActorCompiler Include="ThreadHelper.actor.h" />
<ActorCompiler Include="IndexedSet.actor.h" />
<ActorCompiler Include="Stats.actor.cpp" />
<ActorCompiler Include="Net2.actor.cpp" />
<ActorCompiler Include="genericactors.actor.cpp" />
<ActorCompiler Include="genericactors.actor.h" />
<ActorCompiler Include="Profiler.actor.cpp" />
<ActorCompiler Include="EventTypes.actor.h" />
<ActorCompiler Include="CompressedInt.actor.cpp" />
<ActorCompiler Include="TDMetric.actor.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="boost.cpp" />
<ClCompile Include="Error.cpp" />
<ClCompile Include="FastAlloc.cpp" />
<ClCompile Include="Hash3.c" />
<ClCompile Include="IndexedSet.cpp" />
<ClCompile Include="SystemMonitor.cpp" />
<ClCompile Include="ThreadPrimitives.cpp" />
<ClCompile Include="Platform.cpp" />
<ClCompile Include="Trace.cpp" />
<ClCompile Include="Knobs.cpp" />
<ClCompile Include="TDMetric.cpp" />
<ClCompile Include="UnitTest.cpp" />
<ClCompile Include="Deque.cpp" />
<ClCompile Include="flow.cpp" />
<ClCompile Include="FaultInjection.cpp" />
<ClCompile Include="IThreadPool.cpp" />
<ClCompile Include="network.cpp" />
<ClCompile Include="Net2Packet.cpp" />
<ClCompile Include="ThreadHelper.cpp" />
<ClCompile Include="version.cpp" />
<ClCompile Include="stacktrace.amalgamation.cpp" />
<ClCompile Include="SignalSafeUnwind.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ActorCollection.h" />
<ClInclude Include="actorcompiler.h" />
<ClInclude Include="Arena.h" />
<ClInclude Include="DeterministicRandom.h" />
<ClInclude Include="Error.h" />
<ClInclude Include="error_definitions.h" />
<ClInclude Include="FastAlloc.h" />
<ClInclude Include="FastRef.h" />
<ClInclude Include="Hash3.h" />
<ClInclude Include="IndexedSet.h" />
<ClInclude Include="IRandom.h" />
<ClInclude Include="IThreadPool.h" />
<ClInclude Include="serialize.h" />
<ClInclude Include="SimpleOpt.h" />
<ClInclude Include="SystemMonitor.h" />
<ClInclude Include="ThreadPrimitives.h" />
<ClInclude Include="Platform.h" />
<ClInclude Include="Trace.h" />
<ClInclude Include="ThreadSafeQueue.h" />
<ClInclude Include="Knobs.h" />
<ClInclude Include="UnitTest.h" />
<ClInclude Include="Stats.h" />
<ClInclude Include="Deque.h" />
<ClInclude Include="IDispatched.h" />
<ClInclude Include="flow.h" />
<ClInclude Include="FaultInjection.h" />
<ClInclude Include="network.h" />
<ClInclude Include="AsioReactor.h" />
<ClInclude Include="Net2Packet.h" />
<ClInclude Include="Profiler.h" />
<ClInclude Include="CompressedInt.h" />
<ClInclude Include="SignalSafeUnwind.h" />
<ClInclude Include="MetricSample.h" />
<ClInclude Include="stacktrace.h" />
</ItemGroup>
<ItemGroup>
<None Include="no_intellisense.opt" />
</ItemGroup>
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ActorCompiler Include="ActorCollection.actor.cpp" />
<ActorCompiler Include="ThreadHelper.actor.h" />
<ActorCompiler Include="IndexedSet.actor.h" />
<ActorCompiler Include="Stats.actor.cpp" />
<ActorCompiler Include="Net2.actor.cpp" />
<ActorCompiler Include="genericactors.actor.cpp" />
<ActorCompiler Include="genericactors.actor.h" />
<ActorCompiler Include="Profiler.actor.cpp" />
<ActorCompiler Include="EventTypes.actor.h" />
<ActorCompiler Include="CompressedInt.actor.cpp" />
<ActorCompiler Include="TDMetric.actor.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="boost.cpp" />
<ClCompile Include="Error.cpp" />
<ClCompile Include="FastAlloc.cpp" />
<ClCompile Include="Hash3.c" />
<ClCompile Include="IndexedSet.cpp" />
<ClCompile Include="SystemMonitor.cpp" />
<ClCompile Include="ThreadPrimitives.cpp" />
<ClCompile Include="Platform.cpp" />
<ClCompile Include="Trace.cpp" />
<ClCompile Include="Knobs.cpp" />
<ClCompile Include="TDMetric.cpp" />
<ClCompile Include="UnitTest.cpp" />
<ClCompile Include="Deque.cpp" />
<ClCompile Include="flow.cpp" />
<ClCompile Include="FaultInjection.cpp" />
<ClCompile Include="IThreadPool.cpp" />
<ClCompile Include="network.cpp" />
<ClCompile Include="Net2Packet.cpp" />
<ClCompile Include="ThreadHelper.cpp" />
<ClCompile Include="version.cpp" />
<ClCompile Include="stacktrace.amalgamation.cpp" />
<ClCompile Include="SignalSafeUnwind.cpp" />
<ClCompile Include="XmlTraceLogFormatter.cpp" />
<ClCompile Include="FileTraceLogWriter.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ActorCollection.h" />
<ClInclude Include="actorcompiler.h" />
<ClInclude Include="Arena.h" />
<ClInclude Include="DeterministicRandom.h" />
<ClInclude Include="Error.h" />
<ClInclude Include="error_definitions.h" />
<ClInclude Include="FastAlloc.h" />
<ClInclude Include="FastRef.h" />
<ClInclude Include="Hash3.h" />
<ClInclude Include="IndexedSet.h" />
<ClInclude Include="IRandom.h" />
<ClInclude Include="IThreadPool.h" />
<ClInclude Include="serialize.h" />
<ClInclude Include="SimpleOpt.h" />
<ClInclude Include="SystemMonitor.h" />
<ClInclude Include="ThreadPrimitives.h" />
<ClInclude Include="Platform.h" />
<ClInclude Include="Trace.h" />
<ClInclude Include="ThreadSafeQueue.h" />
<ClInclude Include="Knobs.h" />
<ClInclude Include="UnitTest.h" />
<ClInclude Include="Stats.h" />
<ClInclude Include="Deque.h" />
<ClInclude Include="IDispatched.h" />
<ClInclude Include="flow.h" />
<ClInclude Include="FaultInjection.h" />
<ClInclude Include="network.h" />
<ClInclude Include="AsioReactor.h" />
<ClInclude Include="Net2Packet.h" />
<ClInclude Include="Profiler.h" />
<ClInclude Include="CompressedInt.h" />
<ClInclude Include="SignalSafeUnwind.h" />
<ClInclude Include="MetricSample.h" />
<ClInclude Include="stacktrace.h" />
<ClInclude Include="XmlTraceLogFormatter.h" />
<ClInclude Include="FileTraceLogWriter.h" />
</ItemGroup>
<ItemGroup>
<None Include="no_intellisense.opt" />
</ItemGroup>
</Project>