зеркало из https://github.com/mozilla/pjs.git
fixes bug 328066 "implement bzip2 compression for sending metrics log" r=bryner
This commit is contained in:
Родитель
3d5382eec2
Коммит
537f19bfd4
|
@ -61,6 +61,11 @@ interface nsIMetricsService : nsISupports
|
|||
void logEvent(in DOMString eventNS, in DOMString event,
|
||||
in nsIPropertyBag eventValues);
|
||||
|
||||
/**
|
||||
* Flush data to disk.
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* Initiate the upload of the current event log. This causes the current
|
||||
* event log to be truncated once the upload completes.
|
||||
|
|
|
@ -59,6 +59,7 @@ REQUIRES = xpcom \
|
|||
layout \
|
||||
widget \
|
||||
xmlextras \
|
||||
libbz2 \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
@ -68,6 +69,8 @@ CPPSRCS = \
|
|||
nsMetricsModule.cpp \
|
||||
$(NULL)
|
||||
|
||||
SHARED_LIBRARY_LIBS += $(DIST)/lib/$(LIB_PREFIX)bz2.$(LIB_SUFFIX)
|
||||
|
||||
EXTRA_DSO_LDOPTS = $(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ nsLoadCollector::OnStateChange(nsIWebProgress *webProgress,
|
|||
rv = props->SetPropertyAsUint64(NS_LITERAL_STRING("loadtime"), loadTime);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsMetricsService *ms = nsMetricsService::GetMetricsService();
|
||||
nsMetricsService *ms = nsMetricsService::get();
|
||||
rv = ms->LogEvent(NS_LITERAL_STRING("load"), props);
|
||||
|
||||
mRequestMap.Remove(request);
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMetricsService, Init)
|
||||
NS_DECL_CLASSINFO(nsMetricsService)
|
||||
|
||||
static NS_METHOD
|
||||
|
@ -70,7 +69,7 @@ static const nsModuleComponentInfo components[] = {
|
|||
NS_METRICSSERVICE_CLASSNAME,
|
||||
NS_METRICSSERVICE_CID,
|
||||
NS_METRICSSERVICE_CONTRACTID,
|
||||
nsMetricsServiceConstructor,
|
||||
nsMetricsService::Create,
|
||||
nsMetricsServiceRegisterSelf,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -78,6 +77,12 @@ static const nsModuleComponentInfo components[] = {
|
|||
NULL,
|
||||
&NS_CLASSINFO_NAME(nsMetricsService),
|
||||
nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::SINGLETON
|
||||
},
|
||||
{
|
||||
NS_METRICSSERVICE_CLASSNAME,
|
||||
NS_METRICSSERVICE_CID,
|
||||
NS_ABOUT_MODULE_CONTRACTID_PREFIX "metrics",
|
||||
nsMetricsService::Create
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -59,6 +59,14 @@
|
|||
#include "nsMultiplexInputStream.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsVariant.h"
|
||||
#include "bzlib.h"
|
||||
|
||||
// Make our MIME type inform the server of possible compression.
|
||||
#ifdef NS_METRICS_SEND_UNCOMPRESSED_DATA
|
||||
#define NS_METRICS_MIME_TYPE "application/vnd.mozilla.metrics"
|
||||
#else
|
||||
#define NS_METRICS_MIME_TYPE "application/vnd.mozilla.metrics.bz2"
|
||||
#endif
|
||||
|
||||
// Flush the event log whenever its size exceeds this number of events.
|
||||
#define NS_EVENTLOG_FLUSH_POINT 64
|
||||
|
@ -70,9 +78,9 @@ PRLogModuleInfo *gMetricsLog;
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS5_CI(nsMetricsService, nsIMetricsService,
|
||||
nsIStreamListener, nsIRequestObserver,
|
||||
nsIObserver, nsITimerCallback)
|
||||
NS_IMPL_ISUPPORTS6_CI(nsMetricsService, nsIMetricsService, nsIAboutModule,
|
||||
nsIStreamListener, nsIRequestObserver, nsIObserver,
|
||||
nsITimerCallback)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMetricsService::LogEvent(const nsAString &eventNS,
|
||||
|
@ -142,7 +150,48 @@ nsMetricsService::LogEvent(const nsAString &eventNS,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (++mEventCount > NS_EVENTLOG_FLUSH_POINT)
|
||||
FlushData();
|
||||
Flush();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMetricsService::Flush()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
PRFileDesc *fd;
|
||||
rv = OpenDataFile(PR_WRONLY | PR_APPEND | PR_CREATE_FILE, &fd);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Serialize our document, then strip off the root start and end tags,
|
||||
// and write it out.
|
||||
|
||||
nsCOMPtr<nsIDOMSerializer> ds =
|
||||
do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(ds, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAutoString docText;
|
||||
rv = ds->SerializeToString(mRoot, docText);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The first '>' will be the end of the root start tag.
|
||||
docText.Cut(0, docText.FindChar('>') + 1);
|
||||
|
||||
// The last '<' will be the beginning of the root end tag.
|
||||
PRInt32 start = docText.RFindChar('<');
|
||||
docText.Cut(start, docText.Length() - start);
|
||||
|
||||
NS_ConvertUTF16toUTF8 utf8Doc(docText);
|
||||
PRInt32 num = utf8Doc.Length();
|
||||
PRBool succeeded = ( PR_Write(fd, utf8Doc.get(), num) == num );
|
||||
|
||||
PR_Close(fd);
|
||||
NS_ENSURE_STATE(succeeded);
|
||||
|
||||
// Create a new mRoot
|
||||
rv = CreateRoot();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -152,16 +201,21 @@ nsMetricsService::Upload()
|
|||
if (mUploading) // Ignore new uploads issued while uploading.
|
||||
return NS_OK;
|
||||
|
||||
// We suspend logging until the upload completes.
|
||||
// XXX Download filtering rules and apply them.
|
||||
|
||||
nsresult rv = FlushData();
|
||||
nsresult rv = Flush();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = UploadData();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mUploading = PR_TRUE;
|
||||
Suspend();
|
||||
}
|
||||
|
||||
// Since UploadData is uploading a copy of the data, we can delete the
|
||||
// original data file, and allow new events to be logged to a new file.
|
||||
nsCOMPtr<nsILocalFile> dataFile;
|
||||
GetDataFile(&dataFile);
|
||||
if (dataFile)
|
||||
dataFile->Remove(PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -181,6 +235,24 @@ nsMetricsService::Resume()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMetricsService::NewChannel(nsIURI *uri, nsIChannel **result)
|
||||
{
|
||||
nsresult rv = Flush();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILocalFile> dataFile;
|
||||
GetDataFile(&dataFile);
|
||||
NS_ENSURE_STATE(dataFile);
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
OpenCompleteXMLStream(dataFile, getter_AddRefs(stream));
|
||||
NS_ENSURE_STATE(stream);
|
||||
|
||||
return NS_NewInputStreamChannel(result, uri, stream,
|
||||
NS_LITERAL_CSTRING("text/xml"), nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMetricsService::OnStartRequest(nsIRequest *request, nsISupports *context)
|
||||
{
|
||||
|
@ -191,12 +263,10 @@ NS_IMETHODIMP
|
|||
nsMetricsService::OnStopRequest(nsIRequest *request, nsISupports *context,
|
||||
nsresult status)
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> dataFile;
|
||||
GetDataFile(&dataFile);
|
||||
if (dataFile)
|
||||
dataFile->Remove(PR_FALSE);
|
||||
nsCOMPtr<nsILocalFile> uploadFile = do_QueryInterface(context);
|
||||
if (uploadFile)
|
||||
uploadFile->Remove(PR_FALSE);
|
||||
|
||||
Resume();
|
||||
mUploading = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -215,7 +285,7 @@ nsMetricsService::Observe(nsISupports *subject, const char *topic,
|
|||
const PRUnichar *data)
|
||||
{
|
||||
if (strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
FlushData();
|
||||
Flush();
|
||||
nsLoadCollector::Shutdown();
|
||||
nsWindowCollector::Shutdown();
|
||||
} else if (strcmp(topic, "profile-after-change") == 0) {
|
||||
|
@ -240,6 +310,37 @@ nsMetricsService::Notify(nsITimer *timer)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/*static*/ nsMetricsService *
|
||||
nsMetricsService::get()
|
||||
{
|
||||
if (!sMetricsService) {
|
||||
nsCOMPtr<nsIMetricsService> ms =
|
||||
do_GetService(NS_METRICSSERVICE_CONTRACTID);
|
||||
if (!sMetricsService)
|
||||
NS_WARNING("failed to initialize metrics service");
|
||||
}
|
||||
return sMetricsService;
|
||||
}
|
||||
|
||||
/*static*/ NS_METHOD
|
||||
nsMetricsService::Create(nsISupports *outer, const nsIID &iid, void **result)
|
||||
{
|
||||
NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
|
||||
|
||||
nsRefPtr<nsMetricsService> ms;
|
||||
if (!sMetricsService) {
|
||||
ms = new nsMetricsService();
|
||||
if (!ms)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ASSERTION(sMetricsService, "should be non-null");
|
||||
|
||||
nsresult rv = ms->Init();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
return sMetricsService->QueryInterface(iid, result);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMetricsService::Init()
|
||||
{
|
||||
|
@ -321,47 +422,6 @@ nsMetricsService::OpenDataFile(PRUint32 flags, PRFileDesc **fd)
|
|||
return dataFile->OpenNSPRFileDesc(flags, 0600, fd);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMetricsService::FlushData()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
PRFileDesc *fd;
|
||||
rv = OpenDataFile(PR_WRONLY | PR_APPEND | PR_CREATE_FILE, &fd);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Serialize our document, then strip off the root start and end tags,
|
||||
// and write it out.
|
||||
|
||||
nsCOMPtr<nsIDOMSerializer> ds =
|
||||
do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(ds, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAutoString docText;
|
||||
rv = ds->SerializeToString(mRoot, docText);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The first '>' will be the end of the root start tag.
|
||||
docText.Cut(0, docText.FindChar('>') + 1);
|
||||
|
||||
// The last '<' will be the beginning of the root end tag.
|
||||
PRInt32 start = docText.RFindChar('<');
|
||||
docText.Cut(start, docText.Length() - start);
|
||||
|
||||
NS_ConvertUTF16toUTF8 utf8Doc(docText);
|
||||
PRInt32 num = utf8Doc.Length();
|
||||
PRBool succeeded = ( PR_Write(fd, utf8Doc.get(), num) == num );
|
||||
|
||||
PR_Close(fd);
|
||||
NS_ENSURE_STATE(succeeded);
|
||||
|
||||
// Create a new mRoot
|
||||
rv = CreateRoot();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMetricsService::UploadData()
|
||||
{
|
||||
|
@ -381,7 +441,7 @@ nsMetricsService::UploadData()
|
|||
return NS_ERROR_ABORT;
|
||||
|
||||
nsCOMPtr<nsILocalFile> file;
|
||||
nsresult rv = GetDataFile(&file);
|
||||
nsresult rv = GetDataFileForUpload(&file);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// NOTE: nsIUploadChannel requires a buffered stream to upload...
|
||||
|
@ -397,32 +457,8 @@ nsMetricsService::UploadData()
|
|||
if (streamLen == 0)
|
||||
return NS_ERROR_ABORT;
|
||||
|
||||
// Construct a full XML document using the header, file contents, and
|
||||
// footer.
|
||||
#define METRICS_XML_HEAD "<?xml version=\"1.0\"?>\n" \
|
||||
"<log xmlns=\"http://www.mozilla.org/metrics\">\n"
|
||||
#define METRICS_XML_TAIL "</log>"
|
||||
|
||||
nsCOMPtr<nsIMultiplexInputStream> miStream =
|
||||
do_CreateInstance(NS_MULTIPLEXINPUTSTREAM_CONTRACTID);
|
||||
NS_ENSURE_STATE(miStream);
|
||||
|
||||
nsCOMPtr<nsIInputStream> stringStream;
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(stringStream),
|
||||
NS_LITERAL_CSTRING(METRICS_XML_HEAD));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = miStream->AppendStream(stringStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = miStream->AppendStream(fileStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = NS_NewCStringInputStream(getter_AddRefs(stringStream),
|
||||
NS_LITERAL_CSTRING(METRICS_XML_TAIL));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = miStream->AppendStream(stringStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIInputStream> uploadStream;
|
||||
NS_NewBufferedInputStream(getter_AddRefs(uploadStream), miStream, 4096);
|
||||
NS_NewBufferedInputStream(getter_AddRefs(uploadStream), fileStream, 4096);
|
||||
NS_ENSURE_STATE(uploadStream);
|
||||
|
||||
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
||||
|
@ -435,7 +471,7 @@ nsMetricsService::UploadData()
|
|||
nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(channel);
|
||||
NS_ENSURE_STATE(uploadChannel);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(binaryType, "application/vnd.mozilla.metrics");
|
||||
NS_NAMED_LITERAL_CSTRING(binaryType, NS_METRICS_MIME_TYPE);
|
||||
rv = uploadChannel->SetUploadStream(uploadStream, binaryType, -1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -444,12 +480,134 @@ nsMetricsService::UploadData()
|
|||
rv = httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = channel->AsyncOpen(this, nsnull);
|
||||
rv = channel->AsyncOpen(this, file);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMetricsService::GetDataFileForUpload(nsCOMPtr<nsILocalFile> *result)
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> input;
|
||||
nsresult rv = GetDataFile(&input);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIInputStream> src;
|
||||
rv = OpenCompleteXMLStream(input, getter_AddRefs(src));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> temp;
|
||||
rv = input->Clone(getter_AddRefs(temp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString leafName;
|
||||
rv = temp->GetNativeLeafName(leafName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
leafName.AppendLiteral(".bz2");
|
||||
rv = temp->SetNativeLeafName(leafName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILocalFile> ltemp = do_QueryInterface(temp, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
FILE *destFp = NULL;
|
||||
rv = ltemp->OpenANSIFileDesc("wb", &destFp);
|
||||
|
||||
// Copy file using bzip2 compression:
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
#ifdef NS_METRICS_SEND_UNCOMPRESSED_DATA
|
||||
char buf[4096];
|
||||
PRUint32 n;
|
||||
|
||||
while (NS_SUCCEEDED(rv = src->Read(buf, sizeof(buf), &n)) && n) {
|
||||
if (fwrite(buf, 1, n, destFp) != n) {
|
||||
NS_WARNING("failed to write data");
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
int bzerr = BZ_OK;
|
||||
BZFILE *destBz = BZ2_bzWriteOpen(&bzerr, destFp,
|
||||
9, // block size (1-9)
|
||||
0, // verbosity
|
||||
0); // work factor
|
||||
if (destBz) {
|
||||
char buf[4096];
|
||||
PRUint32 n;
|
||||
|
||||
while (NS_SUCCEEDED(rv = src->Read(buf, sizeof(buf), &n)) && n) {
|
||||
BZ2_bzWrite(&bzerr, destBz, buf, n);
|
||||
if (bzerr != BZ_OK) {
|
||||
NS_WARNING("failed to write data");
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BZ2_bzWriteClose(&bzerr, destBz,
|
||||
0, // abandon
|
||||
nsnull, // nbytes_in
|
||||
nsnull); // nbytes_out
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (destFp)
|
||||
fclose(destFp);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*result = nsnull;
|
||||
ltemp.swap(*result);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMetricsService::OpenCompleteXMLStream(nsILocalFile *dataFile,
|
||||
nsIInputStream **result)
|
||||
{
|
||||
// Construct a full XML document using the header, file contents, and
|
||||
// footer.
|
||||
static const char METRICS_XML_HEAD[] =
|
||||
"<?xml version=\"1.0\"?>\n"
|
||||
"<log xmlns=\"http://www.mozilla.org/metrics\">\n";
|
||||
static const char METRICS_XML_TAIL[] = "</log>";
|
||||
|
||||
nsCOMPtr<nsIInputStream> fileStream;
|
||||
NS_NewLocalFileInputStream(getter_AddRefs(fileStream), dataFile);
|
||||
NS_ENSURE_STATE(fileStream);
|
||||
|
||||
nsCOMPtr<nsIMultiplexInputStream> miStream =
|
||||
do_CreateInstance(NS_MULTIPLEXINPUTSTREAM_CONTRACTID);
|
||||
NS_ENSURE_STATE(miStream);
|
||||
|
||||
nsCOMPtr<nsIInputStream> stringStream;
|
||||
NS_NewByteInputStream(getter_AddRefs(stringStream), METRICS_XML_HEAD,
|
||||
sizeof(METRICS_XML_HEAD)-1);
|
||||
NS_ENSURE_STATE(stringStream);
|
||||
|
||||
nsresult rv = miStream->AppendStream(stringStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = miStream->AppendStream(fileStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_NewByteInputStream(getter_AddRefs(stringStream), METRICS_XML_TAIL,
|
||||
sizeof(METRICS_XML_TAIL)-1);
|
||||
NS_ENSURE_STATE(stringStream);
|
||||
|
||||
rv = miStream->AppendStream(stringStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*result = miStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsMetricsUtils::PutUint16(nsIWritablePropertyBag *bag,
|
||||
const nsAString &propertyName,
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "nsIMetricsService.h"
|
||||
#include "nsMetricsModule.h"
|
||||
#include "nsIAboutModule.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIObserver.h"
|
||||
|
@ -68,6 +69,7 @@ extern PRLogModuleInfo *gMetricsLog;
|
|||
// periodically.
|
||||
|
||||
class nsMetricsService : public nsIMetricsService
|
||||
, public nsIAboutModule
|
||||
, public nsIStreamListener
|
||||
, public nsIObserver
|
||||
, public nsITimerCallback
|
||||
|
@ -75,11 +77,31 @@ class nsMetricsService : public nsIMetricsService
|
|||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMETRICSSERVICE
|
||||
NS_DECL_NSIABOUTMODULE
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
// Get the metrics service singleton. This method will call do_GetService if
|
||||
// necessary to fetch the metrics service. It relies on the service manager
|
||||
// to keep the singleton instance alive. This method may return null!
|
||||
static nsMetricsService* get();
|
||||
|
||||
// Create the metrics service singleton, called only by the XPCOM factory for
|
||||
// this class.
|
||||
static NS_METHOD Create(nsISupports *outer, const nsIID &iid, void **result);
|
||||
|
||||
// Helper function for logging events in the default namespace
|
||||
nsresult LogEvent(const nsAString &eventName,
|
||||
nsHashPropertyBag *eventProperties)
|
||||
{
|
||||
return LogEvent(NS_LITERAL_STRING(NS_METRICS_NAMESPACE),
|
||||
eventName,
|
||||
NS_STATIC_CAST(nsIWritablePropertyBag*, eventProperties));
|
||||
}
|
||||
|
||||
private:
|
||||
nsMetricsService()
|
||||
: mEventCount(0),
|
||||
mSuspendCount(0),
|
||||
|
@ -94,34 +116,21 @@ public:
|
|||
NS_ASSERTION(sMetricsService == this, ">1 MetricsService object created");
|
||||
sMetricsService = nsnull;
|
||||
}
|
||||
|
||||
|
||||
nsresult Init();
|
||||
|
||||
static nsMetricsService* GetMetricsService()
|
||||
{
|
||||
if (!sMetricsService) {
|
||||
nsCOMPtr<nsIMetricsService> ms =
|
||||
do_GetService(NS_METRICSSERVICE_CONTRACTID);
|
||||
}
|
||||
return sMetricsService;
|
||||
}
|
||||
|
||||
nsresult LogEvent(const nsAString &eventName,
|
||||
nsHashPropertyBag *eventProperties)
|
||||
{
|
||||
return LogEvent(NS_LITERAL_STRING(NS_METRICS_NAMESPACE),
|
||||
eventName,
|
||||
NS_STATIC_CAST(nsIWritablePropertyBag*, eventProperties));
|
||||
}
|
||||
|
||||
private:
|
||||
// Creates a new root element to hold event nodes
|
||||
nsresult CreateRoot();
|
||||
|
||||
nsresult FlushData();
|
||||
nsresult UploadData();
|
||||
nsresult GetDataFile(nsCOMPtr<nsILocalFile> *result);
|
||||
nsresult OpenDataFile(PRUint32 flags, PRFileDesc **result);
|
||||
nsresult GetDataFileForUpload(nsCOMPtr<nsILocalFile> *result);
|
||||
|
||||
// This method returns an input stream containing the complete XML for the
|
||||
// data to upload.
|
||||
nsresult OpenCompleteXMLStream(nsILocalFile *dataFile,
|
||||
nsIInputStream **result);
|
||||
|
||||
private:
|
||||
// Pointer to the metrics service singleton
|
||||
|
|
|
@ -159,7 +159,7 @@ nsWindowCollector::Observe(nsISupports *subject,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsMetricsService *ms = nsMetricsService::GetMetricsService();
|
||||
nsMetricsService *ms = nsMetricsService::get();
|
||||
rv = ms->LogEvent(NS_LITERAL_STRING("windowcreate"), properties);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (strcmp(topic, "toplevel-window-ready") == 0) {
|
||||
|
@ -186,7 +186,7 @@ nsWindowCollector::Observe(nsISupports *subject,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsMetricsService *ms = nsMetricsService::GetMetricsService();
|
||||
nsMetricsService *ms = nsMetricsService::get();
|
||||
rv = ms->LogEvent(NS_LITERAL_STRING("windowopen"), properties);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (strcmp(topic, "domwindowclosed") == 0) {
|
||||
|
@ -203,7 +203,7 @@ nsWindowCollector::Observe(nsISupports *subject,
|
|||
GetWindowID(window));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsMetricsService *ms = nsMetricsService::GetMetricsService();
|
||||
nsMetricsService *ms = nsMetricsService::get();
|
||||
rv = ms->LogEvent(NS_LITERAL_STRING("windowclose"), properties);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (strcmp(topic, NS_WEBNAVIGATION_DESTROY) == 0 ||
|
||||
|
@ -221,7 +221,7 @@ nsWindowCollector::Observe(nsISupports *subject,
|
|||
GetWindowID(window));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsMetricsService *ms = nsMetricsService::GetMetricsService();
|
||||
nsMetricsService *ms = nsMetricsService::get();
|
||||
rv = ms->LogEvent(NS_LITERAL_STRING("windowdestroy"), properties);
|
||||
|
||||
// Remove the window from our map.
|
||||
|
|
Загрузка…
Ссылка в новой задаче