Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/metrics/serialization/serialization_utils.h" | 5 #include "components/metrics/serialization/serialization_utils.h" |
| 6 | 6 |
| 7 #include <sys/file.h> | 7 #include <sys/file.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 | 115 |
| 116 void SerializationUtils::ReadAndTruncateMetricsFromFile( | 116 void SerializationUtils::ReadAndTruncateMetricsFromFile( |
| 117 const std::string& filename, | 117 const std::string& filename, |
| 118 ScopedVector<MetricSample>* metrics) { | 118 ScopedVector<MetricSample>* metrics) { |
| 119 struct stat stat_buf; | 119 struct stat stat_buf; |
| 120 int result; | 120 int result; |
| 121 | 121 |
| 122 result = stat(filename.c_str(), &stat_buf); | 122 result = stat(filename.c_str(), &stat_buf); |
| 123 if (result < 0) { | 123 if (result < 0) { |
| 124 if (errno != ENOENT) | 124 if (errno != ENOENT) |
| 125 DPLOG(ERROR) << filename << ": bad metrics file stat"; | 125 DPLOG(ERROR) << filename << ": bad metrics file stat" << " : " << errno; |
|
ostap
2015/04/06 22:12:34
Please, make message consistent - filename after m
| |
| 126 | 126 |
| 127 // Nothing to collect---try later. | 127 // Nothing to collect---try later. |
| 128 return; | 128 return; |
| 129 } | 129 } |
| 130 if (stat_buf.st_size == 0) { | 130 if (stat_buf.st_size == 0) { |
| 131 // Also nothing to collect. | 131 // Also nothing to collect. |
| 132 return; | 132 return; |
| 133 } | 133 } |
| 134 base::ScopedFD fd(open(filename.c_str(), O_RDWR)); | 134 base::ScopedFD fd(open(filename.c_str(), O_RDWR)); |
| 135 if (fd.get() < 0) { | 135 if (fd.get() < 0) { |
| 136 DPLOG(ERROR) << filename << ": cannot open"; | 136 DPLOG(ERROR) << " cannot open: " << filename << " : " << errno; |
| 137 return; | 137 return; |
| 138 } | 138 } |
| 139 result = flock(fd.get(), LOCK_EX); | 139 result = flock(fd.get(), LOCK_EX); |
| 140 if (result < 0) { | 140 if (result < 0) { |
| 141 DPLOG(ERROR) << filename << ": cannot lock"; | 141 DPLOG(ERROR) << "cannot lock: " << filename << " : " << errno; |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 | 144 |
| 145 // This processes all messages in the log. When all messages are | 145 // This processes all messages in the log. When all messages are |
| 146 // read and processed, or an error occurs, truncate the file to zero size. | 146 // read and processed, or an error occurs, truncate the file to zero size. |
| 147 for (;;) { | 147 for (;;) { |
| 148 std::string message; | 148 std::string message; |
| 149 | 149 |
| 150 if (!ReadMessage(fd.get(), &message)) | 150 if (!ReadMessage(fd.get(), &message)) |
| 151 break; | 151 break; |
| 152 | 152 |
| 153 scoped_ptr<MetricSample> sample = ParseSample(message); | 153 scoped_ptr<MetricSample> sample = ParseSample(message); |
| 154 if (sample) | 154 if (sample) |
| 155 metrics->push_back(sample.release()); | 155 metrics->push_back(sample.release()); |
| 156 } | 156 } |
| 157 | 157 |
| 158 result = ftruncate(fd.get(), 0); | 158 result = ftruncate(fd.get(), 0); |
| 159 if (result < 0) | 159 if (result < 0) |
| 160 DPLOG(ERROR) << "truncate metrics log"; | 160 DPLOG(ERROR) << "truncate metrics log: " << filename << " : " << errno; |
| 161 | 161 |
| 162 result = flock(fd.get(), LOCK_UN); | 162 result = flock(fd.get(), LOCK_UN); |
| 163 if (result < 0) | 163 if (result < 0) |
| 164 DPLOG(ERROR) << "unlock metrics log"; | 164 DPLOG(ERROR) << "unlock metrics log: " << filename << " : " << errno; |
| 165 } | 165 } |
| 166 | 166 |
| 167 bool SerializationUtils::WriteMetricToFile(const MetricSample& sample, | 167 bool SerializationUtils::WriteMetricToFile(const MetricSample& sample, |
| 168 const std::string& filename) { | 168 const std::string& filename) { |
| 169 if (!sample.IsValid()) | 169 if (!sample.IsValid()) |
| 170 return false; | 170 return false; |
| 171 | 171 |
| 172 base::ScopedFD file_descriptor(open(filename.c_str(), | 172 base::ScopedFD file_descriptor(open(filename.c_str(), |
| 173 O_WRONLY | O_APPEND | O_CREAT, | 173 O_WRONLY | O_APPEND | O_CREAT, |
| 174 READ_WRITE_ALL_FILE_FLAGS)); | 174 READ_WRITE_ALL_FILE_FLAGS)); |
| 175 | 175 |
| 176 if (file_descriptor.get() < 0) { | 176 if (file_descriptor.get() < 0) { |
| 177 DLOG(ERROR) << "error openning the file"; | 177 DLOG(ERROR) << "error openning the file: " << filename << " : " << errno; |
| 178 return false; | 178 return false; |
| 179 } | 179 } |
| 180 | 180 |
| 181 fchmod(file_descriptor.get(), READ_WRITE_ALL_FILE_FLAGS); | 181 fchmod(file_descriptor.get(), READ_WRITE_ALL_FILE_FLAGS); |
| 182 // Grab a lock to avoid chrome truncating the file | 182 // Grab a lock to avoid chrome truncating the file |
| 183 // underneath us. Keep the file locked as briefly as possible. | 183 // underneath us. Keep the file locked as briefly as possible. |
| 184 // Freeing file_descriptor will close the file and and remove the lock. | 184 // Freeing file_descriptor will close the file and and remove the lock. |
| 185 if (HANDLE_EINTR(flock(file_descriptor.get(), LOCK_EX)) < 0) { | 185 if (HANDLE_EINTR(flock(file_descriptor.get(), LOCK_EX)) < 0) { |
| 186 DLOG(ERROR) << "error locking" << filename << " : " << errno; | 186 DLOG(ERROR) << "error locking" << filename << " : " << errno; |
| 187 return false; | 187 return false; |
| 188 } | 188 } |
| 189 | 189 |
| 190 std::string msg = sample.ToString(); | 190 std::string msg = sample.ToString(); |
| 191 int32 size = msg.length() + sizeof(int32); | 191 int32 size = msg.length() + sizeof(int32); |
| 192 if (size > kMessageMaxLength) { | 192 if (size > kMessageMaxLength) { |
| 193 DLOG(ERROR) << "cannot write message: too long"; | 193 DLOG(ERROR) << "cannot write message: too long" << " : " << errno; |
| 194 return false; | 194 return false; |
| 195 } | 195 } |
| 196 | 196 |
| 197 // The file containing the metrics samples will only be read by programs on | 197 // The file containing the metrics samples will only be read by programs on |
| 198 // the same device so we do not check endianness. | 198 // the same device so we do not check endianness. |
| 199 if (!base::WriteFileDescriptor(file_descriptor.get(), | 199 if (!base::WriteFileDescriptor(file_descriptor.get(), |
| 200 reinterpret_cast<char*>(&size), | 200 reinterpret_cast<char*>(&size), |
| 201 sizeof(size))) { | 201 sizeof(size))) { |
| 202 DPLOG(ERROR) << "error writing message length"; | 202 DPLOG(ERROR) << "error writing message length" << " : " << errno; |
| 203 return false; | 203 return false; |
| 204 } | 204 } |
| 205 | 205 |
| 206 if (!base::WriteFileDescriptor( | 206 if (!base::WriteFileDescriptor( |
| 207 file_descriptor.get(), msg.c_str(), msg.size())) { | 207 file_descriptor.get(), msg.c_str(), msg.size())) { |
| 208 DPLOG(ERROR) << "error writing message"; | 208 DPLOG(ERROR) << "error writing message" << " : " << errno; |
| 209 return false; | 209 return false; |
| 210 } | 210 } |
| 211 | 211 |
| 212 return true; | 212 return true; |
| 213 } | 213 } |
| 214 | 214 |
| 215 } // namespace metrics | 215 } // namespace metrics |
| OLD | NEW |