1 package System::Introspector::State;
3 use System::Introspector::Gatherer;
5 use JSON::Diffable qw( encode_json );
7 has config => (is => 'ro', required => 1);
9 has introspectors => (is => 'lazy');
11 has host => (is => 'ro');
13 has user => (is => 'ro');
15 has sudo_user => (is => 'ro');
17 has storage => (is => 'ro', required => 1);
19 has node_path => (is => 'lazy');
23 my $spec = $self->introspectors;
25 push(@{ $spec->{$_}{sudo} ? \@sudo : \@nosudo}, [$_, $spec->{$_}])
29 my $gatherer = $self->_create_gatherer;
30 %report = %{ $self->_fetch_with_gatherer($gatherer, @nosudo) || {} };
33 my $gatherer = $self->_create_gatherer(sudo => 1);
34 %report = (%report, %{ $self->_fetch_with_gatherer($gatherer, @sudo) || {} });
39 sub _fetch_with_gatherer {
40 my ($self, $gatherer, @spec) = @_;
42 for my $class_spec (@spec) {
43 my ($class_base, $args) = @$class_spec;
44 print "Gathering $class_base data\n";
45 $report{ $class_base } = $gatherer
46 ->gather($class_base, $args);
48 print "All gathered\n";
54 my $data = $self->fetch;
55 return $self->_store($data);
58 sub _build_node_path {
60 return defined($self->host)
61 ? sprintf('host/%s', $self->host)
65 sub _build_introspectors {
67 return $self->config->{introspect};
71 my ($self, $data) = @_;
72 my $storage = $self->storage;
74 for my $class (sort keys %$data) {
75 my $file = sprintf '%s.json', join '/',
76 node => $self->node_path,
78 s{([a-z0-9])([A-Z])}{${1}_${2}}g;
80 } split m{::}, $class;
81 my $fh = $storage->open('>:utf8', $file, mkpath => 1);
82 print "Writing $file\n";
83 print $fh encode_json($data->{$class});
84 push @files, $storage->file($file);
86 $self->_cleanup(\@files);
91 my ($self, $known_files) = @_;
92 my %known = map { ($_ => 1) } @$known_files;
93 my $data_dir = $self->storage->file(node => $self->node_path);
94 my @files = $self->storage->find_files('yml', node => $self->node_path);
95 for my $file (@files) {
96 next if $known{$file};
97 print "Removing $file\n";
99 or die "Unable to remove '$file': $!\n";
104 sub _create_gatherer {
105 my ($self, %arg) = @_;
106 return System::Introspector::Gatherer->new_from_spec(
109 sudo_user => $arg{sudo} && $self->sudo_user,
117 System::Introspector::State - Gather system state
121 my $state = System::Introspector::State->new(
122 host => 'foo.example.com',
123 storage => $storage_obj,
125 introspect => [qw( ProbeName )],
129 my $data = $state->fetch;
130 $state->fetch_and_store;
134 Gathers system introspection data based on configuration and stores
135 it with a L<File::Tree::Snapshot> object.
141 A hash reference containing a C<introspect> key with an array reference
142 value containing a list of probe names without the
143 C<System::Introspector::Probe::> prefix. This attribute is required.
147 An optional hostname. If no hostname is supplied, the local configuration
148 data will be fetched.
152 A L<File::Tree::Snapshot> object.
158 my $data = $state->fetch;
160 Fetches all probe data.
162 =head2 fetch_and_store
164 $state->fetch_and_store;
166 Fetches all probe data and stores it in the L</storage>.