Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: chrome/installer/setup/persistent_histogram_storage.cc

Issue 2335313002: Always persist histograms from setup.exe. (Closed)
Patch Set: rename files Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/installer/setup/installer_metrics.h" 5 #include "chrome/installer/setup/persistent_histogram_storage.h"
6 6
7 #include <windows.h> // NOLINT
8 #include <atlsecurity.h>
9
10 #include "base/files/file_enumerator.h"
11 #include "base/files/file_path.h" 7 #include "base/files/file_path.h"
12 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
13 #include "base/files/important_file_writer.h" 9 #include "base/files/important_file_writer.h"
10 #include "base/logging.h"
14 #include "base/metrics/histogram_base.h" 11 #include "base/metrics/histogram_base.h"
15 #include "base/metrics/persistent_histogram_allocator.h" 12 #include "base/metrics/persistent_histogram_allocator.h"
16 #include "base/metrics/persistent_memory_allocator.h" 13 #include "base/metrics/persistent_memory_allocator.h"
17 #include "base/strings/string_piece.h" 14 #include "base/strings/string_piece.h"
18 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
19 #include "base/time/time.h" 16 #include "base/time/time.h"
20 #include "chrome/installer/util/util_constants.h" 17 #include "chrome/installer/util/util_constants.h"
21 18
22 namespace installer { 19 namespace installer {
23 20
24 namespace { 21 PersistentHistogramStorage::PersistentHistogramStorage() {
25
26 // This is duplicated from components/metrics/file_metrics_provider.h which is
27 // not accessible from setup code.
28 const base::FilePath::CharType MetricsFileExtension[] =
29 FILE_PATH_LITERAL(".pma");
30
31 // Add to the ACL of an object on disk. This follows the method from MSDN:
32 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa379283.aspx
33 // This is done using explicit flags rather than the "security string" format
34 // because strings do not necessarily read what is written which makes it
35 // difficult to de-dup. Working with the binary format is always exact and
36 // the system libraries will properly ignore duplicate ACL entries.
37 bool AddAclToPath(const base::FilePath& path,
38 const CSid& trustee,
39 ACCESS_MASK access_mask,
40 BYTE ace_flags) {
41 DCHECK(!path.empty());
42 DCHECK(trustee);
43
44 // Get the existing DACL.
45 ATL::CDacl dacl;
46 if (!ATL::AtlGetDacl(path.value().c_str(), SE_FILE_OBJECT, &dacl)) {
47 DPLOG(ERROR) << "Failed getting DACL for path \"" << path.value() << "\"";
48 return false;
49 }
50
51 // Check if the requested access already exists and return if so.
52 for (UINT i = 0; i < dacl.GetAceCount(); ++i) {
53 ATL::CSid sid;
54 ACCESS_MASK mask = 0;
55 BYTE type = 0;
56 BYTE flags = 0;
57 dacl.GetAclEntry(i, &sid, &mask, &type, &flags);
58 if (sid == trustee && type == ACCESS_ALLOWED_ACE_TYPE &&
59 (flags & ace_flags) == ace_flags &&
60 (mask & access_mask) == access_mask) {
61 return true;
62 }
63 }
64
65 // Add the new access to the DACL.
66 if (!dacl.AddAllowedAce(trustee, access_mask, ace_flags)) {
67 DPLOG(ERROR) << "Failed adding ACE to DACL";
68 return false;
69 }
70
71 // Attach the updated ACL as the object's DACL.
72 if (!ATL::AtlSetDacl(path.value().c_str(), SE_FILE_OBJECT, dacl)) {
73 DPLOG(ERROR) << "Failed setting DACL for path \"" << path.value() << "\"";
74 return false;
75 }
76
77 return true;
78 }
79
80 } // namespace
81
82 base::FilePath GetPersistentHistogramStorageDir(
83 const base::FilePath& target_path) {
84 return target_path.AppendASCII(kSetupHistogramAllocatorName);
85 }
86
87 void BeginPersistentHistogramStorage() {
88 base::GlobalHistogramAllocator::CreateWithLocalMemory( 22 base::GlobalHistogramAllocator::CreateWithLocalMemory(
89 1 << 20, // 1 MiB 23 1 << 20, // 1 MiB
90 0, // No identifier. 24 0, // No identifier.
91 installer::kSetupHistogramAllocatorName); 25 installer::kSetupHistogramAllocatorName);
grt (UTC plus 2) 2016/09/13 19:42:59 nit: remove "installer::"
fdoray 2016/09/13 20:18:25 Done.
92 base::GlobalHistogramAllocator::Get()->CreateTrackingHistograms( 26 base::GlobalHistogramAllocator::Get()->CreateTrackingHistograms(
93 kSetupHistogramAllocatorName); 27 kSetupHistogramAllocatorName);
94 28
95 // This can't be enabled until after the allocator is configured because 29 // This can't be enabled until after the allocator is configured because there
96 // there is no other reporting out of setup other than persistent memory. 30 // is no other reporting out of setup other than persistent memory.
97 base::HistogramBase::EnableActivityReportHistogram("setup"); 31 base::HistogramBase::EnableActivityReportHistogram("setup");
98 } 32 }
99 33
100 void EndPersistentHistogramStorage(const base::FilePath& target_path, 34 PersistentHistogramStorage::~PersistentHistogramStorage() {
101 bool system_install) {
102 base::PersistentHistogramAllocator* allocator = 35 base::PersistentHistogramAllocator* allocator =
103 base::GlobalHistogramAllocator::Get(); 36 base::GlobalHistogramAllocator::Get();
104 allocator->UpdateTrackingHistograms(); 37 allocator->UpdateTrackingHistograms();
105 38
106 // Allocator dumps are saved to a directory that was created earlier. Stop 39 // Stop if |storage_dir_| isn't set or does not exist. That can happen if the
107 // now if that directory has been removed because an uninstall has happened. 40 // product hasn't been installed yet or if it has been uninstalled.
108 base::FilePath dir_path = GetPersistentHistogramStorageDir(target_path); 41 if (storage_dir_.empty() || !base::DirectoryExists(storage_dir_))
109 if (!base::DirectoryExists(dir_path))
110 return; 42 return;
111 43
112 // Set permissions on the directory that allows other processes, including
113 // non-privileged ones, to read and delete the files stored there. This
114 // allows the browser process to remove the metrics files once it's done
115 // reading them. This is only done for system-level installs; user-level
116 // installs already provide delete-file access to the browser process.
117 if (system_install) {
118 if (!AddAclToPath(dir_path, ATL::Sids::AuthenticatedUser(),
119 FILE_GENERIC_READ | FILE_DELETE_CHILD,
120 CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)) {
121 PLOG(ERROR) << "Could not set \"delete\" permission for metrics directory"
122 << " \"" << dir_path.value() << "\"";
123 }
124 }
125
126 // Remove any existing metrics file at the old (non-subdir) pathname.
127 base::DeleteFile(dir_path.AddExtension(MetricsFileExtension), false);
128
129 // Save data using the current time as the filename. The actual filename 44 // Save data using the current time as the filename. The actual filename
130 // doesn't matter (so long as it ends with the correct extension) but this 45 // doesn't matter (so long as it ends with the correct extension) but this
131 // works as well as anything. 46 // works as well as anything.
132 base::Time::Exploded exploded; 47 base::Time::Exploded exploded;
133 base::Time::Now().LocalExplode(&exploded); 48 base::Time::Now().LocalExplode(&exploded);
134 base::FilePath file_path = 49 const base::FilePath file_path =
135 dir_path 50 storage_dir_
136 .AppendASCII(base::StringPrintf("%04d%02d%02d%02d%02d%02d", 51 .AppendASCII(base::StringPrintf("%04d%02d%02d%02d%02d%02d",
137 exploded.year, exploded.month, 52 exploded.year, exploded.month,
138 exploded.day_of_month, exploded.hour, 53 exploded.day_of_month, exploded.hour,
139 exploded.minute, exploded.second)) 54 exploded.minute, exploded.second))
140 .AddExtension(MetricsFileExtension); 55 .AddExtension(base::PersistentMemoryAllocator::kFileExtension);
141 56
142 base::StringPiece contents(static_cast<const char*>(allocator->data()), 57 base::StringPiece contents(static_cast<const char*>(allocator->data()),
143 allocator->used()); 58 allocator->used());
144 if (base::ImportantFileWriter::WriteFileAtomically(file_path, contents)) 59 if (base::ImportantFileWriter::WriteFileAtomically(file_path, contents))
145 VLOG(1) << "Persistent histograms saved in file: " << file_path.value(); 60 VLOG(1) << "Persistent histograms saved in file: " << file_path.value();
146 } 61 }
147 62
63 base::FilePath PersistentHistogramStorage::GetStorageDir(
grt (UTC plus 2) 2016/09/13 19:42:59 nit: // static before this
fdoray 2016/09/13 20:18:25 Done.
64 const base::FilePath& target_path) {
65 return target_path.AppendASCII(kSetupHistogramAllocatorName);
66 }
67
148 } // namespace installer 68 } // namespace installer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698