LCOV - code coverage report
Current view: top level - media/mtransport - rlogconnector.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 87 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 et sw=2 tw=80: */
       3             : 
       4             : /* This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       6             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       7             : 
       8             : /* Original author: bcampen@mozilla.com */
       9             : 
      10             : #include <cstdarg>
      11             : 
      12             : #include "rlogconnector.h"
      13             : 
      14             : #include <deque>
      15             : #include <string>
      16             : #include "logging.h"
      17             : #include "mozilla/Assertions.h"
      18             : #include "mozilla/Move.h" // Pinch hitting for <utility> and std::move
      19             : #include "mozilla/Mutex.h"
      20             : #include "mozilla/Sprintf.h"
      21             : #include <vector>
      22             : 
      23             : extern "C" {
      24             : #include <csi_platform.h>
      25             : #include "r_log.h"
      26             : #include "registry.h"
      27             : }
      28             : 
      29             : /* Matches r_dest_vlog type defined in r_log.h */
      30           0 : static int ringbuffer_vlog(int facility,
      31             :                            int level,
      32             :                            const char *format,
      33             :                            va_list ap) {
      34           0 :   MOZ_ASSERT(mozilla::RLogConnector::GetInstance());
      35             :   // I could be evil and printf right into a std::string, but unless this
      36             :   // shows up in profiling, it is not worth doing.
      37             :   char temp[4096];
      38           0 :   VsprintfLiteral(temp, format, ap);
      39             : 
      40           0 :   mozilla::RLogConnector::GetInstance()->Log(level, std::string(temp));
      41           0 :   return 0;
      42             : }
      43             : 
      44           0 : static mozilla::LogLevel rLogLvlToMozLogLvl(int level) {
      45           0 :   switch (level) {
      46             :     case LOG_EMERG:
      47             :     case LOG_ALERT:
      48             :     case LOG_CRIT:
      49             :     case LOG_ERR:
      50           0 :       return mozilla::LogLevel::Error;
      51             :     case LOG_WARNING:
      52           0 :       return mozilla::LogLevel::Warning;
      53             :     case LOG_NOTICE:
      54           0 :       return mozilla::LogLevel::Info;
      55             :     case LOG_INFO:
      56           0 :       return mozilla::LogLevel::Debug;
      57             :     case LOG_DEBUG:
      58             :     default:
      59           0 :       return mozilla::LogLevel::Verbose;
      60             :   }
      61             : }
      62             : 
      63           0 : MOZ_MTLOG_MODULE("nicer");
      64             : 
      65             : namespace mozilla {
      66             : 
      67             : RLogConnector* RLogConnector::instance;
      68             : 
      69           0 : RLogConnector::RLogConnector()
      70             :   : log_limit_(4096),
      71             :     mutex_("RLogConnector::mutex_"),
      72           0 :     disableCount_(0) {
      73           0 : }
      74             : 
      75           0 : RLogConnector::~RLogConnector() {
      76           0 : }
      77             : 
      78           0 : void RLogConnector::SetLogLimit(uint32_t new_limit) {
      79           0 :   OffTheBooksMutexAutoLock lock(mutex_);
      80           0 :   log_limit_ = new_limit;
      81           0 :   RemoveOld();
      82           0 : }
      83             : 
      84           0 : void RLogConnector::Log(int level, std::string&& log) {
      85           0 :   MOZ_MTLOG(rLogLvlToMozLogLvl(level), log);
      86             : 
      87           0 :   if (level <= LOG_INFO) {
      88           0 :     OffTheBooksMutexAutoLock lock(mutex_);
      89           0 :     if (disableCount_ == 0) {
      90           0 :       AddMsg(Move(log));
      91             :     }
      92             :   }
      93           0 : }
      94             : 
      95           0 : void RLogConnector::AddMsg(std::string&& msg) {
      96           0 :   log_messages_.push_front(Move(msg));
      97           0 :   RemoveOld();
      98           0 : }
      99             : 
     100           0 : inline void RLogConnector::RemoveOld() {
     101           0 :   if (log_messages_.size() > log_limit_) {
     102           0 :     log_messages_.resize(log_limit_);
     103             :   }
     104           0 : }
     105             : 
     106           0 : RLogConnector* RLogConnector::CreateInstance() {
     107           0 :   if (!instance) {
     108           0 :     instance = new RLogConnector;
     109           0 :     NR_reg_init(NR_REG_MODE_LOCAL);
     110           0 :     r_log_set_extra_destination(LOG_DEBUG, &ringbuffer_vlog);
     111             :   }
     112           0 :   return instance;
     113             : }
     114             : 
     115           0 : RLogConnector* RLogConnector::GetInstance() {
     116           0 :   return instance;
     117             : }
     118             : 
     119           0 : void RLogConnector::DestroyInstance() {
     120             :   // First param is ignored when passing null
     121           0 :   r_log_set_extra_destination(LOG_DEBUG, nullptr);
     122           0 :   delete instance;
     123           0 :   instance = nullptr;
     124           0 : }
     125             : 
     126             : // As long as at least one PeerConnection exists in a Private Window rlog messages will not
     127             : // be saved in the RLogConnector. This is necessary because the log_messages buffer
     128             : // is shared across all instances of PeerConnectionImpls. There is no way with the current
     129             : // structure of r_log to run separate logs.
     130             : 
     131           0 : void RLogConnector::EnterPrivateMode() {
     132           0 :   OffTheBooksMutexAutoLock lock(mutex_);
     133           0 :   ++disableCount_;
     134           0 :   MOZ_ASSERT(disableCount_ != 0);
     135             : 
     136           0 :   if (disableCount_ == 1) {
     137           0 :     AddMsg("LOGGING SUSPENDED: a connection is active in a Private Window ***");
     138             :   }
     139           0 : }
     140             : 
     141           0 : void RLogConnector::ExitPrivateMode() {
     142           0 :   OffTheBooksMutexAutoLock lock(mutex_);
     143           0 :   MOZ_ASSERT(disableCount_ != 0);
     144             : 
     145           0 :   if (--disableCount_ == 0) {
     146           0 :     AddMsg("LOGGING RESUMED: no connections are active in a Private Window ***");
     147             :   }
     148           0 : }
     149             : 
     150           0 : void RLogConnector::Clear() {
     151           0 :   OffTheBooksMutexAutoLock lock(mutex_);
     152           0 :   log_messages_.clear();
     153           0 : }
     154             : 
     155           0 : void RLogConnector::Filter(const std::string& substring,
     156             :                             uint32_t limit,
     157             :                             std::deque<std::string>* matching_logs) {
     158           0 :   std::vector<std::string> substrings;
     159           0 :   substrings.push_back(substring);
     160           0 :   FilterAny(substrings, limit, matching_logs);
     161           0 : }
     162             : 
     163           0 : inline bool AnySubstringMatches(const std::vector<std::string>& substrings,
     164             :                                 const std::string& string) {
     165           0 :   for (auto sub = substrings.begin(); sub != substrings.end(); ++sub) {
     166           0 :     if (string.find(*sub) != std::string::npos) {
     167           0 :       return true;
     168             :     }
     169             :   }
     170           0 :   return false;
     171             : }
     172             : 
     173           0 : void RLogConnector::FilterAny(const std::vector<std::string>& substrings,
     174             :                                uint32_t limit,
     175             :                                std::deque<std::string>* matching_logs) {
     176           0 :   OffTheBooksMutexAutoLock lock(mutex_);
     177           0 :   if (limit == 0) {
     178             :     // At a max, all of the log messages.
     179           0 :     limit = log_limit_;
     180             :   }
     181             : 
     182           0 :   for (auto log = log_messages_.begin();
     183           0 :        log != log_messages_.end() && matching_logs->size() < limit;
     184             :        ++log) {
     185           0 :     if (AnySubstringMatches(substrings, *log)) {
     186           0 :       matching_logs->push_front(*log);
     187             :     }
     188             :   }
     189           0 : }
     190             : 
     191             : } // namespace mozilla

Generated by: LCOV version 1.13