App-Device-Chip-sensor

 view release on metacpan or  search on metacpan

bin/device-chip-sensor-exporter  view on Meta::CPAN

      # Config file is YAML and can override a number of settings, and add chips
      my $config = YAML::LoadFile( $path );

      if( $config->{adapters} ) {
         foreach my $c ( ( delete $config->{adapters} )->@* ) {
            my $type = delete $c->{type} // croak "Expected adapter config to have a 'type'";
            my $chips = delete $c->{chips} // croak "Expected adapter config to have a 'chips'";

            # TODO: It'd be really nice if Device::Chip::Adapter->make( $type, %opts ) existed
            my $desc = $type . join( ":", "", map { "$_=$c->{$_}" } sort keys %$c );
            my $adapter = Device::Chip::Adapter->new_from_description( $desc );

            foreach my $c ( $chips->@* ) {
               my ( $type, %config ) = ( reftype($c)//"" eq "HASH" )
                  ? ( delete $c->{type}, $c->%* )
                  : ( $c, () );

               $self->add_chip(
                  type      => $type,
                  adapter   => $adapter,
                  mountopts => $config{mountopts},
                  config    => $config{config},
               );
            }
         }
      }

      if( exists $config->{port} ) {
         $PORT = $config->{port};
         delete $config->{port};
      }

      foreach my $opt (qw( interval best_effort filter )) {
         exists $config->{$opt} and
            $self->$opt = delete $config->{$opt};
      }

      # Legacy support
      exists $config->{mid3} and
         $self->filter = "mid3", delete $config->{mid3};

      die "Unrecognised config file items " . join( ", ", sort keys %$config ) . "\n"
         if keys %$config;
   }

   async method after_sensors :override ( @sensors )
   {
      my %got;

      foreach my $sensor ( @sensors ) {
         my $name = $sensor->name;
         my $units = $sensor->units;

         my $chip = $sensor->chip;
         my $chipname = ( ref $chip ) =~ s/^Device::Chip:://r;

         # Convert some common characters that Prometheus will get upset by
         if( defined $units ) {
            $units =~ s{/}{_per_};

            $units =~ s/%/percentage/g;
            $units =~ s/°/degrees/g;
            $units =~ s/µ/micro/g;

            $units =~ s/m²/square_metre/g;
            $units =~ s/m³/cubic_metre/g;
         }

         $got{$name}++ and next;

         my $m = "make_" . $sensor->type;
         $metrics->$m( $name,
            name        => join( "_", "sensor", $name, grep { defined } $units ),
            description => "Sensor $name",
            labels      => [qw( chip )],
         );

         $metrics->inc_counter_by( chip_failures => 0, [ chip => $chipname ] );
      }
   }

   # Count the failures per reading round
   field %failures_per_chip;
   # Counts in total
   field %chip_failures;

   method output_readings ( $now, $sensors, $values )
   {
      if( $VERBOSE ) {
         printf "At %s\n", strftime( $STRFTIME, localtime );
         $self->print_readings( $sensors, $values );
      }

      foreach my $i ( 0 .. $#$sensors ) {
         my $sensor = $sensors->[$i];
         my $value  = $values->[$i];

         my $chip = $sensor->chip;
         my $chipname = ( ref $chip ) =~ s/^Device::Chip:://r;

         my $m = ( $sensor->type eq "gauge" )   ? "set_gauge_to" :
                 ( $sensor->type eq "counter" ) ? "inc_counter_by" :
                                                  die "Unrecognised sensor type";
         $metrics->$m( $sensor->name,
            $self->_format_reading( $sensor, $value ), [ chip => $chipname ] );
      }

      foreach my $chipaddr ( keys %failures_per_chip ) {
         if( ++$chip_failures{ $chipaddr } >= 5 ) {
            die "This sensor chip has failed 5 times in a row; aborting\n";
         }
         if( keys %chip_failures >= 3 ) {
            die "Three or more sensor chips have failed; aborting\n";
         }
      }
      undef %failures_per_chip;
   }

   method on_sensor_fail ( $sensor, $failure ) {
      $self->SUPER::on_sensor_fail( $sensor, $failure );



( run in 1.573 second using v1.01-cache-2.11-cpan-39bf76dae61 )