Como configurar o Apache para não manter access.log ou error.log abertos o tempo todo para virtualhosts?

1

Eu quero diminuir o número de arquivos abertos no meu VPS. Com o lsof, percebi que o Apache constantemente mantém o access.log e o error.log abertos para cada domínio hospedado no servidor.

Existe uma maneira de mudar esse comportamento?

    
por Ned-ster 12.12.2012 / 12:07

2 respostas

1

Muitos arquivos abertos geralmente não são um problema. Há um limite de sistema, que você pode verificar usando o comando sysctl fs.file-max - no meu sistema CentOS 6 com 4GB de RAM é 382299, que deve ser suficiente, e em 256MB a VM eu iniciei era 23539, o que pode ser um pouco pequeno. Mas você pode aumentar esse limite facilmente, por exemplo, adicionando a /etc/sysctl.conf :

fs.file-max = 500000

Em seguida, execute sysctl -p ou reinicialize.

Você pode escrever um programa que irá abrir, escrever, fechar um arquivo de log toda vez que os dados forem recebidos de stdin, e usá-lo assim:

CustomLog "||open-write-close /var/log/httpd/access_log" common

mas não será eficiente. E não será fácil, já que seria necessário usar o IO assíncrono.

Eu escrevi um programa para isso em C:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>

int outfd;

int main(int argn, char* argv[])
{
    if (argn != 2) {
        fprintf(stderr, "Usage %s [output_file]\n", argv[0]);
        return 1;
    }

    {
        long stdinflags = fcntl(0,F_GETFL);
        if ( stdinflags == -1 ) {
            perror("fcntl: Can't read stdin status");
            return 2;
        }
        if ( fcntl(0,F_SETFL,stdinflags|O_NONBLOCK) == -1 ) {
            perror("fcntl: Can't set stdin to non-blocking mode");
            return 2;
        }
    }


    do {
        #define BUFSIZE PIPE_BUF
        char buf[BUFSIZE];
        ssize_t bytesread = read(0, buf, BUFSIZE);

        {
            fd_set select_fdset;
            FD_ZERO(&select_fdset);
            FD_SET(0, &select_fdset);
            if ( select(1, &select_fdset, NULL, NULL, NULL) == -1 ) {
                if ( errno != EINTR ) {
                    perror("select");
                    return 2;
                }
            };
        }
        if ( bytesread==-1 ) {
            perror("Can't read from stdin");
            return 2;
        }
        if ( bytesread == 0 ) break;
        outfd = open(argv[1],O_WRONLY|O_APPEND|O_CREAT);
        if ( outfd < 0 ) {
            fprintf(stderr, "Can't open file \"%s\": %s\n", argv[1], strerror(errno));
            return 2;
        }
        do {
            if ( write(outfd, buf, bytesread) == -1 ) {
                fprintf(stderr, "Can't write to file \"%s\": %s\n", argv[1], strerror(errno));
                return 2;
            };
            bytesread = read(0, buf, BUFSIZE);
            if ( bytesread==-1 ) {
                if ( errno==EAGAIN ) break;
                perror("Can't read from stdin");
            }
        } while ( bytesread>0 );
        if ( close(outfd) != 0) {
            fprintf(stderr, "Can't close file \"%s\": %s\n", argv[1], strerror(errno));
            return 2;
        }
    } while ( 1 );
    return 0;
}
    
por 12.12.2012 / 16:34
0

Se você tiver um grande número de vhosts com arquivos de log de acesso separados, sugiro que registre tudo em um arquivo (Sim, elimine o CustomLog em cada vhost) e depois use o aplicativo split-logfile separe-os. Você pode se juntar a ele com o script logresolve , para resolver nomes DNS.

Para o trabalho split-logfile , você precisa definir a primeira coluna em CustomLog para ServerName.

    
por 12.12.2012 / 16:39