Home | History | Annotate | Download | only in probes
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SRC_TRACED_PROBES_PROBES_PRODUCER_H_
     18 #define SRC_TRACED_PROBES_PROBES_PRODUCER_H_
     19 
     20 #include <map>
     21 #include <memory>
     22 #include <utility>
     23 
     24 #include "perfetto/base/task_runner.h"
     25 #include "perfetto/base/watchdog.h"
     26 #include "perfetto/ftrace_reader/ftrace_controller.h"
     27 #include "perfetto/tracing/core/producer.h"
     28 #include "perfetto/tracing/core/trace_writer.h"
     29 #include "perfetto/tracing/ipc/producer_ipc_client.h"
     30 #include "src/traced/probes/filesystem/inode_file_data_source.h"
     31 #include "src/traced/probes/process_stats_data_source.h"
     32 
     33 #include "perfetto/trace/filesystem/inode_file_map.pbzero.h"
     34 
     35 namespace perfetto {
     36 
     37 const uint64_t kLRUInodeCacheSize = 1000;
     38 
     39 class ProbesProducer : public Producer {
     40  public:
     41   ProbesProducer();
     42   ~ProbesProducer() override;
     43 
     44   // Producer Impl:
     45   void OnConnect() override;
     46   void OnDisconnect() override;
     47   void CreateDataSourceInstance(DataSourceInstanceID,
     48                                 const DataSourceConfig&) override;
     49   void TearDownDataSourceInstance(DataSourceInstanceID) override;
     50   void OnTracingSetup() override;
     51   void Flush(FlushRequestID,
     52              const DataSourceInstanceID* data_source_ids,
     53              size_t num_data_sources) override;
     54 
     55   // Our Impl
     56   void ConnectWithRetries(const char* socket_name,
     57                           base::TaskRunner* task_runner);
     58   bool CreateFtraceDataSourceInstance(TracingSessionID session_id,
     59                                       DataSourceInstanceID id,
     60                                       const DataSourceConfig& config);
     61   void CreateProcessStatsDataSourceInstance(TracingSessionID session_id,
     62                                             DataSourceInstanceID id,
     63                                             const DataSourceConfig& config);
     64   void CreateInodeFileDataSourceInstance(TracingSessionID session_id,
     65                                          DataSourceInstanceID id,
     66                                          DataSourceConfig config);
     67 
     68   void OnMetadata(const FtraceMetadata& metadata);
     69 
     70  private:
     71   using FtraceBundleHandle =
     72       protozero::MessageHandle<protos::pbzero::FtraceEventBundle>;
     73   using FtraceStatsHandle =
     74       protozero::MessageHandle<protos::pbzero::FtraceStats>;
     75 
     76   class SinkDelegate : public FtraceSink::Delegate {
     77    public:
     78     SinkDelegate(TracingSessionID,
     79                  base::TaskRunner*,
     80                  std::unique_ptr<TraceWriter>);
     81     ~SinkDelegate() override;
     82 
     83     TracingSessionID session_id() const { return session_id_; }
     84 
     85     void Flush();
     86 
     87     // FtraceDelegateImpl
     88     FtraceBundleHandle GetBundleForCpu(size_t cpu) override;
     89     void OnBundleComplete(size_t cpu,
     90                           FtraceBundleHandle bundle,
     91                           const FtraceMetadata& metadata) override;
     92     void OnCreate(FtraceSink*) override;
     93 
     94     void WriteStats();
     95 
     96     void set_sink(std::unique_ptr<FtraceSink> sink) { sink_ = std::move(sink); }
     97 
     98     void set_ps_source(base::WeakPtr<ProcessStatsDataSource> ptr) {
     99       ps_source_ = std::move(ptr);
    100     }
    101     const base::WeakPtr<ProcessStatsDataSource>& ps_source() const {
    102       return ps_source_;
    103     }
    104 
    105     void set_file_source(base::WeakPtr<InodeFileDataSource> ptr) {
    106       file_source_ = std::move(ptr);
    107     }
    108     const base::WeakPtr<InodeFileDataSource>& file_source() const {
    109       return file_source_;
    110     }
    111 
    112    private:
    113     const TracingSessionID session_id_;
    114     base::TaskRunner* task_runner_;
    115     std::unique_ptr<FtraceSink> sink_ = nullptr;
    116     std::unique_ptr<TraceWriter> writer_;
    117     FtraceStats stats_before_ = {};
    118 
    119     base::WeakPtr<ProcessStatsDataSource> ps_source_;
    120     base::WeakPtr<InodeFileDataSource> file_source_;
    121 
    122     // Keep this after the TraceWriter because TracePackets must not outlive
    123     // their originating writer.
    124     TraceWriter::TracePacketHandle trace_packet_;
    125 
    126     // Keep this last.
    127     base::WeakPtrFactory<SinkDelegate> weak_factory_;
    128   };
    129 
    130   enum State {
    131     kNotStarted = 0,
    132     kNotConnected,
    133     kConnecting,
    134     kConnected,
    135   };
    136 
    137   ProbesProducer(const ProbesProducer&) = delete;
    138   ProbesProducer& operator=(const ProbesProducer&) = delete;
    139 
    140   void Connect();
    141   void Restart();
    142   void ResetConnectionBackoff();
    143   void IncreaseConnectionBackoff();
    144   void AddWatchdogsTimer(DataSourceInstanceID id,
    145                          const DataSourceConfig& source_config);
    146 
    147   State state_ = kNotStarted;
    148   base::TaskRunner* task_runner_ = nullptr;
    149   std::unique_ptr<Service::ProducerEndpoint> endpoint_ = nullptr;
    150   std::unique_ptr<FtraceController> ftrace_ = nullptr;
    151   bool ftrace_creation_failed_ = false;
    152   uint32_t connection_backoff_ms_ = 0;
    153   const char* socket_name_ = nullptr;
    154   std::set<DataSourceInstanceID> failed_sources_;
    155   std::map<DataSourceInstanceID, std::unique_ptr<ProcessStatsDataSource>>
    156       process_stats_sources_;
    157   std::map<DataSourceInstanceID, std::unique_ptr<SinkDelegate>> delegates_;
    158   std::map<DataSourceInstanceID, base::Watchdog::Timer> watchdogs_;
    159   std::map<DataSourceInstanceID, std::unique_ptr<InodeFileDataSource>>
    160       file_map_sources_;
    161   LRUInodeCache cache_{kLRUInodeCacheSize};
    162   std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>
    163       system_inodes_;
    164 };
    165 
    166 }  // namespace perfetto
    167 
    168 #endif  // SRC_TRACED_PROBES_PROBES_PRODUCER_H_
    169