Como encontrar arquivos “crescentes” dentro de um sistema linux

4

Eu tenho um servidor que está constantemente perdendo espaço em disco, então acho que deve haver alguns logs que eu não conheço.

Qual é uma boa maneira de localizar arquivos que estão constantemente aumentando de tamanho?

    
por Tike 03.11.2011 / 04:41

6 respostas

7

Existe um utilitário chamado gt5 que exibe os tamanhos atuais dos diretórios, bem como a diferença da última vez que você verificou.

    
por 20.11.2011 / 18:17
6

você pode usar este comando:

find / -size +100000k

que retornará todos os arquivos com espaço maior que 100 Mega Bytes. você pode diminuir ou aumentar o valor dependendo da sua necessidade.

Ou

Você pode usar um utilitário chamado "ncdu", que cria automaticamente um MAP de tamanho de arquivo / pasta.

    
por 20.11.2011 / 17:28
3

Veja como usar o comando ncdu ( disponível aqui ) para obter uma visão resumida do tamanho do diretório em todo o sistema. Existem apenas alguns locais comuns para verificar um sistema padrão para arquivos de log, portanto, isso deve ser fácil de monitorar. Este é um bom primeiro passo para a descoberta.

A longo prazo, você deve seguir um destes procedimentos ...

Escreva um script para pesquisar arquivos maiores que um tamanho específico .

A melhor abordagem, no entanto, é provavelmente a manutenção e rotação de logs.

    
por 20.11.2011 / 17:22
0

Existe um script shell simples, ele usa o sqlite para armazenar os dados, para que você possa gerar vários relatórios com ele. Basta adicioná-lo ao seu crontab: /root/bin/diskhogs.sh /directory/to/monitor

O script em si está lá:

#!/bin/sh

# Checking the spool directory
SPOOL="/var/spool/diskhogs"
if [ ! -e "${SPOOL}" ]; then
        mkdir -p "${SPOOL}"
fi
if [ ! -d "${SPOOL}" ]; then
        echo "There are no ${SPOOL} directory" >&2
        exit 1
fi

if [ -z "${1}" ]; then
        DIR=.
else
        DIR="${1}"
fi

FILES=$(find "${DIR}" -type f)

TIME=$(date +%s)
if [ -z "${TIME}" ]; then
        echo "Can't determine current time" >&2
        exit 1
fi

for FILE in ${FILES}; do

        SIZE=$(ls -nl ${FILE} | awk '{ print $5 }')
        if [ -z "${SIZE}" ]; then
                echo "Can't determine size of the ${FILE} file" >&2
                continue
        fi

        sqlite3 "${SPOOL}/db" "INSERT INTO sizes VALUES ('${FILE}', '${TIME}', '${SIZE}');"
        if [ ${?} -ne 0 ]; then
                continue
        fi

done

for PERIOD in 60 300 600 1800 3600 86400; do

        TIME_WAS=$((${TIME} - ${PERIOD}))

        (
                echo "*** Since $(date --date="@${TIME_WAS}") (${PERIOD} seconds ago) ***"
                sqlite3 \
                        "${SPOOL}/db" \
                        "SELECT MAX(size) - MIN(size) AS mm, name
                                FROM sizes
                                WHERE time >= '${TIME_WAS}'
                                GROUP BY name
                                ORDER BY mm
                        ;"
        ) > "${SPOOL}/report_${PERIOD}"

done

Se você precisar gerar mais relatórios personalizados, use o sqlite:

sqlite3 /var/spool/diskhogs/db "
    SELECT MAX(size) - MIN(size) as mm, name
        FROM sizes
        WHERE
            time >= '$(date --date='10 days ago' +%s)' AND
            name like '/var/lib/libvirt/images/%'
        GROUP BY name
        ORDER BY mm DESC
    ;"

Se eu tiver algumas ideias sobre como melhorá-lo, atualizarei no GitHub: link

    
por 14.02.2015 / 10:24
0

A ferramenta ncdu mencionada acima é uma ferramenta muito boa e provavelmente o melhor caminho a seguir.

Mas se você está sob pressão e quer apenas uma maneira rápida e suja de descobrir o que está acontecendo. Basta executar o abaixo de / (root)

    [root /]# cd /
    [root /]# du -sm * | sort -nr | head 
    3755    usr    
    151     var   
    109     boot  
    29      etc

    [root /]# cd usr  
    [root usr]# du -sm * | sort -nr | head  
    1618    share  
    1026    lib64  
    572     lib  
    237     bin

    [root usr]# cd share  
    [root share]# du -sm * | sort -nr | head  
    415     locale  
    255     icons  
    185     help  
    143     doc  
    [root share]# du -sm * | sort -nr | head   
    415     locale  
    255     icons   
    185     help   
    [root share]# cd locale  
    [root locale]# du -sm * | sort -nr | head   
    12      uk  
    12      de  
    [root locale]#

E assim por diante para encontrar e rastrear quais diretórios e arquivos são ocupados com muito espaço.

    
por 14.02.2015 / 11:31
-1

Eu encontrei este prático script perl em algum lugar anos atrás e usei-o desde então. Funciona muito bem todas as vezes :-) O (s) autor (es) estão listados no topo, não aceito nenhum crédito por isso.

#!/usr/bin/perl
#
# dur - Disk|Directory Usage Reporter
#       Perl utility to check disk space utilisation
#
# The utility displays the disk usage:
#    - total number of files
#    - top big files
#    - extra info: aging files, directories
#
# USAGE: dur [-d] [-Tn] directory
#   eg, dur /usr           # top 5 big files for /usr
#       dur -T5 /opt       # top 5 big files for /opt
#       dur -T10 /         # top 10 big files for /
#       dur -d /opt        # directory usage for /opt
#
#
# NOTES:
# It is highly recommended to use standard File::Find Perl module
# when trying to process each file from a deep directory structure. 
# Some folks are writting their own rutine based on find(1) in Perl. 
# This sometimes will be slower than File::Find so make sure you 
# test this before you will run it in live production systems.
#
# There are a lot of talks over File::Find and its memory consumption and
# how can you minimize that. Basically it very much depends. I found that
# File::Find is much faster in Solaris 10 with a target directory of +1mil
# files than any custom perl script calling find(1M).
#
# You will see a memory usage increase but the script will be faster. The
# deeper the directory is the more memory will use.
#
#  Example:
#   You can easily check how dur works against a big deep directory,
#   over +1mil files:
#
#   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP      
# 19667 sparvu    228M  219M sleep   20    0   0:01:36 8.6% dur/1
#
#
# SEE ALSO:
#  http://www.perlmonks.org/?node_id=325146
#  
#
# COPYRIGHT: Copyright (c) 2007 Stefan Parvu
#
# 10-Dec-2006    Stefan Parvu    First Version, nawk to perl
# 02-May-2007       "      "     Added top variable for big files
# 13-May-2007       "      "     Added dir_usage subroutine
# 19-May-2007       "      "     Added comments, Perl Best Practices

use warnings;
use strict;
use File::Find;
use Getopt::Std;
use Time::HiRes qw(gettimeofday);


###########
# Variables
###########
my %files = ();
my %dirs = ();
my @sorted;
$|=1;
my $size = 0;
my $mtime = 0;
my $current_time = 0;

############################
#  Process command line args
############################
usage() if (($#ARGV+1)==0);
usage() if defined $ARGV[0] and $ARGV[0] eq "-h";
getopts('dT:s:') or usage();
my $topN  = defined $main::opt_T ? $main::opt_T : 5;
my $dirFlag = defined $main::opt_d ? $main::opt_d : 0;
my $secs = defined $main::opt_s ? $main::opt_s : 0;


#########################################
# Usage        : find(\&fileCount, @ARGV)
# Purpose      : counts the number, 
#              : of bytes of each file
# Returns      : A hash with all files
# Parameters   : 
# Comments     : Used from File::Find
# See Also     : n/a
#########################################
sub fileCount {
    if (-f $_) {
        if ($secs != 0) {
            $mtime = (stat($_))[9];
            #if ($mtime  $secs) {
                $files{$File::Find::name} = -s;
            }
        }
        else {
            $files{$File::Find::name} = -s;
        }
    }
    $mtime = 0;
}




#########################################
# Usage        : find(\&fileCount, @ARGV)
# Purpose      : counts the number,
#              : of bytes
# Returns      : scalar variable, with
#              : total number of bytes
# Parameters   :
# Comments     : Used from File::Find 
# See Also     : n/a
#########################################
sub dirCount {
    if (-f) {
        $size += -s;
    }
}

#########################################
# Usage        : dir_usage()
# Purpose      : reports the directory
#              : usage
# Returns      : n/a
# Parameters   : @ARGV
# Comments     : Calls File::Find
# See Also     : dirCount()
#########################################
sub dir_usage() {
    my $target = $ARGV[0];

    print "Processing directories...\n";

    opendir(D, $target) or 
    die("Couldn't open $target for reading: $!\n");

    chdir "$target";
    foreach (readdir D) {
        next if $_ =~ /^\.\.?$/;
        next if (! -d $_);
        find (\&dirCount, "$_");
        $dirs{$_} = $size;
        $size = 0;
    }

    closedir(D);

    @sorted = sort {$dirs{$b}  $dirs{$a}} keys %dirs;
    foreach (@sorted) {
        printf "%6d MB => %s\n",$dirs{$_}/1048576,$_;
    }
    print "Total directories processed: " . keys(%dirs) . "\n";
}

#########################################
# Usage        : top_files()
# Purpose      : print top N big files
# Returns      : n/a
# Parameters   : @ARGV
# Comments     : Calls File::Find,
#              : default N=5
# See Also     : fileCount()
#########################################
sub top_files {

    print "Processing top $topN big files...\n";

#start counting here
    my $tstart = gettimeofday();

    find(\&fileCount, @ARGV);

    @sorted = sort {$files{$b}  $files{$a}} keys %files;
    splice @sorted, $topN if @sorted > $topN;

#print scalar %files;

    foreach (@sorted) {
        printf "%6d MB => %s\n", $files{$_}/1048576, $_;
    }

    my $tend = gettimeofday();
    my $elapsed = $tend - $tstart;

#end timing
    printf "%s %4.2f %s", "Elapsed:", $elapsed, "seconds\n";
    print "Total files processed: " . keys(%files) . "\n";
}


#########################################
# Usage        : usage()
# Purpose      : print usage and exit
# Returns      : n/a
# Parameters   : n/a
# Comments     : n/a
# See Also     : n/a
#########################################
sub usage {
    print STDERR /dev/null      # directory usage for /opt
    dur -s1200  /                # top 5 big files older than
                                 #  20 minutes for /
    dur -s86400 /                # top 5 big files older than
                                 #  1 day for /
END
    exit 1;
}


######
# Main
######
$current_time = time();

if ($#ARGV > 0) {
    usage();
} elsif ($dirFlag) {
    dir_usage();
} else { 
    top_files();
}
    
por 20.11.2011 / 22:34

Tags