Reputation: 57
I am working on a JSON config file (logstash-forwarder) in which I want to add or remove data with a perl script (It is a script used to deploy or undeploy jboss webapps and it could then be used to update logstash forwarder configuration).
I have no problem with adding and modifying the configuration file but I can't find the right way to remove an object.
Here is an example of the config.json file:
{
"network" : {
"timeout" : 15,
"ssl ca" : "/etc/logstash-forwarder/cert/logstash-forwarder.crt",
"servers" : [
"server1@domain:5043",
"server2@domain:5043"
] },
"files" : [
{
"fields" : {
"environment" : "TEST1,TEST23",
"application" : "application1",
"type" : "jboss"
},
"paths" : [
"/path/to/application1/logs/*.log"
]
},
{
"fields" : {
"environment" : "TEST2",
"application" : "application2",
"type" : "jboss"
},
"paths" : [
"/path/to/application2/logs/*.log"
]
}
]
}
And the part of the code I am using to delete an object (when the webapp is undeployed):
removeLogStashConf
{
use JSON qw(encode_json decode_json);
my ( $application ) = @_;
my $app_path = "/path/to/$application/*.log";
local $/;
open( my $fh, "<", "$Param::logstash_conf_file" );
my $json = <$fh>;
close $fh;
my $data = JSON::decode_json($json); };
my @files = @{ $data->{'files'} };
my $file_level = undef;
foreach my $f (@files) {
my @paths = @{ $f->{"paths"} };
foreach my $path (@paths) {
if ( $path eq $app_path ) {
$file_level = $f;
}
}
}
for (keys %$file_level)
{
delete $file_level->{$_};
}
my $encoded = JSON->new->utf8->pretty->encode($data);
open( $fh, ">", "$Param::logstash_conf_file" );
print $fh $encoded;
}
When I try to remove, say, application2, the result I get in config.json file is:
{
"network" : {
"timeout" : 15,
"ssl ca" : "/etc/logstash-forwarder/cert/logstash-forwarder.crt",
"servers" : [
"server1@domain:5043",
"server2@domain:5043"
] },
"files" : [
{
"fields" : {
"environment" : "TEST1,TEST23",
"application" : "application1",
"type" : "jboss"
},
"paths" : [
"/path/to/application1/logs/*.log"
]
},
{}
]
}
How can I get rid of that remaining empy curly brackets ("{}" or "{}," if I remove an application that is not the last of the array) that prevent me to do further parsing and that let me with an untidy config.json file.
I could surely find a solution with a sed but is there something cleaner?
Thank you in advance for your help.
Upvotes: 1
Views: 2408
Reputation: 2353
Emptying hash is not enough to delete it from array.
You can use splice
or just copy all needed records to a new array:
my $data = JSON::decode_json($json);
my @files = @{ $data->{'files'} };
my @new_files;
foreach my $f (@files) {
my @paths = @{ $f->{paths} };
foreach my $path (@paths) {
unless ( $path eq $app_path ) {
push @new_files, $f;
}
}
}
$data->{files} = \@new_files;
Upvotes: 2