Eu tenho um script que executo usando php artisan (com usuário root ), e às vezes faz com que o arquivo de log diário seja criado antes do usuário www-data do apache - o que significa que quando um usuário real usa meu aplicativo da web, eu obtenho o erro de permissão de pasta:
Falha ao abrir o stream: permissão negada
Eu mudo as permissões de volta para www-data todas as vezes, mas quero resolver isso tendo o arquivo de log sempre criado com as permissões corretas.
Pensei em criar um cron job que cria o arquivo ou o toca para ter certeza de que tem a permissão certa todos os dias, mas estou procurando uma solução melhor que não dependa de outro script.
Também consideramos envolver o php artisan em outro script para ter certeza de que ele sempre será executado com as credenciais www-data , mas algumas coisas que queremos fazer são, na verdade, procedimentos de root que o apache não deve ter permissão para fazer.
Mais alguma sugestão?
cron
trabalho paratouch
um novo arquivo de log à meia-noite todos os dias (com o usuário correto, é claro).php artisan
como o usuário que deseja criar o arquivo de log.sudo crontab -u www-data -e
Respostas:
Vamos começar com o que é constante.
Você tem um
php artisan
comando, executado porroot
.É seguro presumir que esse comando seja executado diariamente.
Solução Nº 1:
Dado que o usuário que cria os arquivos é aquele que tem permissão para gravar neles por padrão, podemos separar os registros por usuário da seguinte forma:
App/start/global.php
Se o seu www-data usuário foram para criar um log de erro, isso resultaria em:
storage/logs/laravel-www-data-2015-4-27.log
.Se a sua raiz usuário fosse para criar um log de erro, isso resultaria em:
storage/logs/laravel-root-2015-4-27.log
.Solução No 2:
Mude o log usado pelo seu comando artisan, em seu script php.
Em sua
run()
função, adicione esta linha no início:Se o nome da sua turma for
ArtisanRunner
, seu arquivo de registro será:storage/logs/laravel-ArtisanRunner-2015-4-27.log
.Conclusão: a solução número 1 é melhor, pois delineia seus logs por usuário e, portanto, nenhum erro ocorrerá.
EDIT: conforme apontado por jason,
get_current_user()
retorna o nome do proprietário do script. Portanto, para a solução nº 1 ser aplicada,chown
seus arquivos de classe de artesão para o nome de usuário necessário.fonte
get_current_user()
retorna o proprietário do script PHP atual (de acordo com php.net) e não o usuário que está executando o script no momento. Eu usophp_sapi_name()
, em vez disso, que fornece o nome do manipulador de php (apache ou cli, por exemplo), que tende a ser executado como usuários diferentes.Laravel versão 5.6.10 e posterior tem suporte para um
permission
elemento na configuração (config/logging.php
) para osingle
e odaily
driver:Não há necessidade de fazer malabarismos com o Monolog no script de bootstrap.
Especificamente, o suporte foi adicionado em https://github.com/laravel/framework/commit/4d31633dca9594c9121afbbaa0190210de28fed8 .
fonte
'permission' => 0664
funciona para mim (sem aspas)Para o Laravel 5.1, uso o seguinte na parte inferior
bootstrap/app.php
(conforme mencionado na documentação ):Existem muitos outros manipuladores que você pode usar em vez disso, é claro.
fonte
Para tais propósitos, você deve usar ACL avançado em seus arquivos e diretórios.
setfacl
seria sua resposta aqui. Se você quiser dar ao usuário www-data permissões para gravar nos arquivos do root em um diretório específico, você pode fazer assim:Após a emissão do presente você está definindo permissões para
rwx
para www-data usuário em todos os arquivos/my/folder/
, não importa o que criou aqueles. Por favor, veja esta e esta pergunta para referência. Além disso, você pode verificar os documentos parasetfacl
.Avise-me se isso ajudar.
fonte
setfacl -d -m g:www-data:rw /full/path/to/laravel/storage/logs
seguido porphp artisan cache:clear
ecomposer dump-autoload
.Eu fiz isso funcionar de maneira muito simples:
Encontrei o mesmo problema no Laravel 5.6
Em
config/logging.php
I acaba de atualizar valor de caminho de canal diário comphp_sapi_name()
nela.Isso cria um diretório separado para diferentes php_sapi_name e coloca o arquivo de log com o carimbo de data / hora em seu diretório perticular.
Então, para mim,
fpm-fcgi
diretório: Logs do site,owner: www-data
cli
diretório: a partir do comando artisan (cronjob).owner: root
Mais informações sobre o registro do Laravel 5.6: https://laravel.com/docs/5.6/logging
Aqui está meu
config/logging.php
arquivo:fonte
artisan config:cache
, uma vez que criará um cache de configuração usando o cli SAPI que será usado para solicitações CLI e web.get_current_user
não funciona, masphp_sapi_name
funciona (embora pareça mais feio)Para mim, esse problema era muito mais do que permissões de registro ... Tive problemas com qualquer coisa relacionada ao bootstrap / cache e pastas de armazenamento onde um usuário criava um arquivo / pasta e o outro não conseguia editar / excluir devido ao padrão 644 e 755 permissões.
Os cenários típicos são:
O arquivo bootstrap / cache / compiled.php sendo criado pelo usuário apache, mas não pode ser editado pelo usuário composer ao executar o comando de instalação do composer
O usuário apache criando o cache que não pode ser limpo usando o usuário composer
O sonho é que não importa qual usuário crie o arquivo / pasta, os outros usuários que precisam acessar têm exatamente as mesmas permissões do autor original.
TL; DR?
Veja como isso é feito.
Precisamos criar um grupo de usuários compartilhado chamado laravel, o grupo consiste em todos os usuários que precisam de acesso aos diretórios de armazenamento e bootstrap / cache. Em seguida, precisamos garantir que os arquivos e pastas recém-criados tenham o grupo laravel e as permissões 664 e 775, respectivamente.
É fácil fazer isso para arquivos / diretórios existentes, mas um pouco de mágica é necessária para ajustar as regras de criação de arquivos / pastas padrão ...
Puramente para fins de depuração, descobri que dividir os logs em ambos os usuários cli / web + foi benéfico, então modifiquei um pouco a resposta de Sam Wilson. Meu caso de uso foi a fila executada sob seu próprio usuário, então ajudou a distinguir entre o usuário do compositor usando o cli (por exemplo, testes de unidade) e o daemon de fila.
fonte
configureMonologUsing
Porém, seu código ainda é necessário, depois de executar ossetfacl
comandos?Laravel 5.1
Em nosso caso, queríamos criar todos os arquivos de log de forma que tudo no
deploy
grupo tivesse permissão de leitura / gravação. Portanto, precisamos criar todos os novos arquivos com0664
permissões, ao contrário do0644
padrão.Também adicionamos um formatador para adicionar novas linhas para melhor legibilidade:
Também é possível combinar isso com a resposta aceita
fonte
Uma maneira não-Laravel de fazer isso funcionar é simplesmente executar seu cronjob como dados www.
por exemplo, /ubuntu/189189/how-to-run-crontab-as-userwww-data
fonte
Laravel 5.5
Adicione este código a
bootstrap/app.php
:laravel-2018-01-27-cli-raph.log
elaravel-2018-01-27-fpm-cgi-raph.log
que são mais legíveis.Laravel 5.6
Você deve criar uma classe para o seu logger:
Então, você deve registrá-lo em
config/logging.php
:Mesmo comportamento do 5.5:
laravel-2018-01-27-cli-raph.log
elaravel-2018-01-27-fpm-cgi-raph.log
que são mais legíveis.fonte
Adicione algo como o seguinte no início do seu
app/start/artisan.php
arquivo (isto é com o Laravel 4):Ajuste o caminho se o arquivo de log diário que você mencionou não for o arquivo de log padrão do Laravel. Você também pode não querer alterar o grupo ou definir as permissões como estou fazendo aqui. O item acima define o grupo como
www-data
e as permissões de gravação do grupo. Em seguida, adicionei meu usuário regular aowww-data
grupo para que a execução de comandos artisan como meu usuário regular ainda possa gravar no log.Um ajuste relacionado é colocar o seguinte no início de seu
app/start/global.php
arquivo:Se você fizer isso, a
chmod
linha acima se tornará discutível. Com o umask definido para isso, quaisquer novos arquivos que o PHP (e, portanto, o Laravel) criar terão suas permissões mascaradas apenas para que "outros" usuários não tenham permissão de gravação. Isso significa que os diretórios começarão comorwxrwxr-x
e os arquivos comorw-rw-r--
. Portanto, sewww-data
estiver executando o PHP, qualquer cache e arquivos de log que ele criar serão graváveis por padrão por qualquer pessoa do grupo principal do usuário, que éwww-data
.fonte
(Laravel 5.6) Recentemente, encontrei o mesmo problema e simplesmente configurei um comando agendado para ser executado
/app/Console/Kernel.php
.$schedule->exec('chown -R www-data:www-data /var/www/**********/storage/logs')->everyMinute();
Eu sei que é um pouco exagerado, mas funciona perfeitamente e não teve nenhum problema desde então.
fonte
Laravel 5.4
\Log::getMonolog()->popHandler(); \Log::useDailyFiles(storage_path('/logs/laravel-').get_current_user().'.log');
adicionar para
boot
funcionar emAppServiceProvider
fonte
Laravel 5.8
Laravel 5.8 permite que você defina o nome do log em
config/logging.php
.Então, usando respostas e comentários anteriores, se você quiser nomear seu log usando o nome de usuário posix real E o
php_sapi_name()
valor, você só precisa alterar o conjunto de nomes de log. Usar o driver diário permite a rotação do log que é executada por combinação de usuário / API, o que garantirá que o log seja sempre girado por uma conta que pode modificar os logs.Eu também adicionei uma verificação para as funções posix que podem não existir em seu ambiente local, caso em que o nome do log apenas assume o padrão.
Supondo que você esteja usando o canal de registro padrão 'diário', você pode modificar sua chave de 'canais' assim:
Isso resultará em um nome de registro que deve ser exclusivo para cada combinação, como
laravel-cli-sfscs-2019-05-15.log
oularavel-apache2handler-apache-2019-05-15.log
dependendo do seu ponto de acesso.fonte
Você pode simplesmente alterar a permissão do arquivo de log em seu comando artisan:
onde get_current_user () retornará o usuário do script atual.
Em outras palavras,
daily.log
sempre teráwww-data
como seu dono, mesmo que inicialize o script comoroot
usuário.fonte
Se você estiver usando o Laravel Envoyer , aqui está uma possível correção usando ACL no Linux:
1. Primeiro, execute o seguinte script com
root
permissões no servidor:2. Configure o seguinte gancho de implantação no envoyer em "Ativar nova versão"> "Antes desta ação
3. Reimplante seu aplicativo
Agora, reimplante seu aplicativo e ele deve funcionar no futuro.
fonte
fonte
A melhor maneira que encontrei é que a sugestão do fideloper, http://fideloper.com/laravel-log-file-name , você pode definir a configuração do log laravel sem tocar na classe Log. Ter nomes diferentes para programas de console e programas Http, eu acho, é a melhor solução.
fonte
Esta solução definitivamente funcionará no Laravel V5.1 - V6.x
Razões para este erro:
.env
arquivo não encontrado em seu diretório raizConsertar:
touch .env
e cole suas variáveis de ambiente e executefonte