diff options
Diffstat (limited to 'indra/newview/llviewerstatsrecorder.cpp')
-rwxr-xr-x | indra/newview/llviewerstatsrecorder.cpp | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp new file mode 100755 index 0000000000..b5ccf4ffa0 --- /dev/null +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -0,0 +1,277 @@ +/** + * @file llviewerstatsrecorder.cpp + * @brief record info about viewer events to a metrics log file + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llviewerstatsrecorder.h" + + +#include "llfile.h" +#include "llviewerregion.h" +#include "llviewerobject.h" + + +// To do - something using region name or global position +#if LL_WINDOWS + static const std::string STATS_FILE_NAME("C:\\ViewerObjectCacheStats.csv"); +#else + static const std::string STATS_FILE_NAME("/tmp/viewerstats.csv"); +#endif + +LLViewerStatsRecorder* LLViewerStatsRecorder::sInstance = NULL; +LLViewerStatsRecorder::LLViewerStatsRecorder() : + mObjectCacheFile(NULL), + mTimer(), + mStartTime(0.0), + mLastSnapshotTime(0.0) +{ + if (NULL != sInstance) + { + LL_ERRS() << "Attempted to create multiple instances of LLViewerStatsRecorder!" << LL_ENDL; + } + sInstance = this; + clearStats(); +} + +LLViewerStatsRecorder::~LLViewerStatsRecorder() +{ + if (mObjectCacheFile != NULL) + { + // last chance snapshot + writeToLog(0.f); + LLFile::close(mObjectCacheFile); + mObjectCacheFile = NULL; + } +} + +void LLViewerStatsRecorder::clearStats() +{ + mObjectCacheHitCount = 0; + mObjectCacheHitSize = 0; + mObjectCacheMissFullCount = 0; + mObjectCacheMissFullSize = 0; + mObjectCacheMissCrcCount = 0; + mObjectCacheMissCrcSize = 0; + mObjectFullUpdates = 0; + mObjectFullUpdatesSize = 0; + mObjectTerseUpdates = 0; + mObjectTerseUpdatesSize = 0; + mObjectCacheMissRequests = 0; + mObjectCacheMissResponses = 0; + mObjectCacheMissResponsesSize = 0; + mObjectCacheUpdateDupes = 0; + mObjectCacheUpdateChanges = 0; + mObjectCacheUpdateAdds = 0; + mObjectCacheUpdateReplacements = 0; + mObjectUpdateFailures = 0; + mObjectUpdateFailuresSize = 0; + mTextureFetchSize = 0; +} + + +void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size) +{ + mObjectUpdateFailures++; + mObjectUpdateFailuresSize += msg_size; +} + +void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size) +{ + if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type) + { + mObjectCacheMissFullCount++; + mObjectCacheMissFullSize += msg_size; + } + else + { + mObjectCacheMissCrcCount++; + mObjectCacheMissCrcSize += msg_size; + } +} + +void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size) +{ + switch (update_type) + { + case OUT_FULL: + mObjectFullUpdates++; + mObjectFullUpdatesSize += msg_size; + break; + case OUT_TERSE_IMPROVED: + mObjectTerseUpdates++; + mObjectTerseUpdatesSize += msg_size; + break; + case OUT_FULL_COMPRESSED: + mObjectCacheMissResponses++; + mObjectCacheMissResponsesSize += msg_size; + break; + case OUT_FULL_CACHED: + mObjectCacheHitCount++; + mObjectCacheHitSize += msg_size; + break; + default: + LL_WARNS() << "Unknown update_type" << LL_ENDL; + break; + }; +} + +void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size) +{ + switch (update_result) + { + case LLViewerRegion::CACHE_UPDATE_DUPE: + mObjectCacheUpdateDupes++; + break; + case LLViewerRegion::CACHE_UPDATE_CHANGED: + mObjectCacheUpdateChanges++; + break; + case LLViewerRegion::CACHE_UPDATE_ADDED: + mObjectCacheUpdateAdds++; + break; + case LLViewerRegion::CACHE_UPDATE_REPLACED: + mObjectCacheUpdateReplacements++; + break; + default: + LL_WARNS() << "Unknown update_result type" << LL_ENDL; + break; + }; +} + +void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count) +{ + mObjectCacheMissRequests += count; +} + +void LLViewerStatsRecorder::writeToLog( F32 interval ) +{ + size_t data_size = 0; + F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime; + S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; + + if ( delta_time < interval || total_objects == 0) return; + + mLastSnapshotTime = LLTimer::getTotalSeconds(); + LL_DEBUGS() << "ILX: " + << mObjectCacheHitCount << " hits, " + << mObjectCacheMissFullCount << " full misses, " + << mObjectCacheMissCrcCount << " crc misses, " + << mObjectFullUpdates << " full updates, " + << mObjectTerseUpdates << " terse updates, " + << mObjectCacheMissRequests << " cache miss requests, " + << mObjectCacheMissResponses << " cache miss responses, " + << mObjectCacheUpdateDupes << " cache update dupes, " + << mObjectCacheUpdateChanges << " cache update changes, " + << mObjectCacheUpdateAdds << " cache update adds, " + << mObjectCacheUpdateReplacements << " cache update replacements, " + << mObjectUpdateFailures << " update failures" + << LL_ENDL; + + if (mObjectCacheFile == NULL) + { + mStartTime = LLTimer::getTotalSeconds(); + mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb"); + if (mObjectCacheFile) + { // Write column headers + std::ostringstream data_msg; + data_msg << "EventTime(ms)\t" + << "Cache Hits\t" + << "Cache Full Misses\t" + << "Cache Crc Misses\t" + << "Full Updates\t" + << "Terse Updates\t" + << "Cache Miss Requests\t" + << "Cache Miss Responses\t" + << "Cache Update Dupes\t" + << "Cache Update Changes\t" + << "Cache Update Adds\t" + << "Cache Update Replacements\t" + << "Update Failures\t" + << "Cache Hits bps\t" + << "Cache Full Misses bps\t" + << "Cache Crc Misses bps\t" + << "Full Updates bps\t" + << "Terse Updates bps\t" + << "Cache Miss Responses bps\t" + << "Texture Fetch bps\t" + << "\n"; + + data_size = data_msg.str().size(); + if (fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ) != data_size) + { + LL_WARNS() << "failed to write full headers to " << STATS_FILE_NAME << LL_ENDL; + } + } + else + { + //LL_WARNS() << "Couldn't open " << STATS_FILE_NAME << " for logging." << LL_ENDL; + return; + } + } + + std::ostringstream data_msg; + + data_msg << getTimeSinceStart() + << "\t " << mObjectCacheHitCount + << "\t" << mObjectCacheMissFullCount + << "\t" << mObjectCacheMissCrcCount + << "\t" << mObjectFullUpdates + << "\t" << mObjectTerseUpdates + << "\t" << mObjectCacheMissRequests + << "\t" << mObjectCacheMissResponses + << "\t" << mObjectCacheUpdateDupes + << "\t" << mObjectCacheUpdateChanges + << "\t" << mObjectCacheUpdateAdds + << "\t" << mObjectCacheUpdateReplacements + << "\t" << mObjectUpdateFailures + << "\t" << (mObjectCacheHitSize * 8 / delta_time) + << "\t" << (mObjectCacheMissFullSize * 8 / delta_time) + << "\t" << (mObjectCacheMissCrcSize * 8 / delta_time) + << "\t" << (mObjectFullUpdatesSize * 8 / delta_time) + << "\t" << (mObjectTerseUpdatesSize * 8 / delta_time) + << "\t" << (mObjectCacheMissResponsesSize * 8 / delta_time) + << "\t" << (mTextureFetchSize * 8 / delta_time) + << "\n"; + + data_size = data_msg.str().size(); + if ( data_size != fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile )) + { + LL_WARNS() << "Unable to write complete column data to " << STATS_FILE_NAME << LL_ENDL; + } + + clearStats(); +} + +F32 LLViewerStatsRecorder::getTimeSinceStart() +{ + return (F32) (LLTimer::getTotalSeconds() - mStartTime); +} + +void LLViewerStatsRecorder::recordTextureFetch( S32 msg_size ) +{ + mTextureFetchSize += msg_size; +} + + + |