บันทึกรายวัน Laravel สร้างขึ้นโดยมีสิทธิ์ที่ไม่ถูกต้อง


112

ฉันมีสคริปต์ที่ฉันเรียกใช้โดยใช้ php artisan (กับผู้ใช้รูท ) และบางครั้งมันทำให้ไฟล์บันทึกรายวันถูกสร้างขึ้นก่อนที่ผู้ใช้ apache www-dataจะทำ - ซึ่งหมายความว่าเมื่อผู้ใช้จริงใช้เว็บแอปพลิเคชันของฉันฉันจะได้รับ ข้อผิดพลาดการอนุญาตโฟลเดอร์:

ไม่สามารถเปิดสตรีม: ปฏิเสธการอนุญาต

ฉันเปลี่ยนสิทธิ์กลับเป็นwww-dataทุกครั้ง แต่ฉันต้องการแก้ปัญหานี้โดยการสร้างไฟล์บันทึกด้วยสิทธิ์ที่ถูกต้องเสมอ

ฉันได้พิจารณาสร้างงาน cron ที่สร้างไฟล์หรือสัมผัสมันเพื่อให้แน่ใจว่าได้รับอนุญาตที่ถูกต้องทุกวัน แต่ฉันกำลังมองหาวิธีแก้ปัญหาที่ดีกว่าที่ไม่ต้องพึ่งพาสคริปต์อื่น

นอกจากนี้เรายังได้พิจารณาการตัด php artisan ในสคริปต์อื่นเพื่อให้แน่ใจว่าจะรันด้วยข้อมูลประจำตัวwww-dataอยู่เสมอแต่บางสิ่งที่เราต้องการทำคือrootโพรซีเดอร์ที่ apache ไม่ควรได้รับอนุญาตให้ทำ

ข้อเสนอแนะเพิ่มเติมหรือไม่?


ตั้งค่าcronงานtouchเป็นไฟล์บันทึกใหม่ตอนเที่ยงคืนของทุกวัน (แน่นอนว่าอยู่ภายใต้ผู้ใช้ที่ถูกต้อง)
Ben Harold

@BenHarold ขอบคุณเราได้พิจารณาแล้ว แต่ฉันไม่อยากเกี่ยวข้องกับสคริปต์มากกว่านี้
NiRR

2
ในกรณีนี้คุณจะต้องเรียกใช้php artisanในฐานะผู้ใช้ที่คุณต้องการสร้างไฟล์บันทึก
Ben Harold

@BenHarold ขอบคุณอีกครั้งเราได้พิจารณาแล้วเช่นกันซึ่งอาจเป็นวิธีที่ดีที่สุด แต่ฉันได้อัปเดตคำถามเพื่ออธิบายว่าเหตุใดจึงไม่เหมาะ
NiRR

2
สิ่งที่ได้ผลสำหรับฉันคือเรียกใช้ cron ในฐานะผู้ใช้ www-data ด้วยsudo crontab -u www-data -e
Nil Llisterri

คำตอบ:


67

เริ่มจากค่าคงที่

คุณมีคำสั่งดำเนินการโดยphp artisanroot

ปลอดภัยที่จะถือว่าคำสั่งนี้ดำเนินการทุกวัน

โซลูชันที่ 1:

เนื่องจากผู้ใช้ที่สร้างไฟล์เป็นผู้ที่ได้รับอนุญาตให้เขียนโดยค่าเริ่มต้นเราสามารถแยกบันทึกตามผู้ใช้ดังนี้:

App/start/global.php

/*
|--------------------------------------------------------------------------
| Application Error Logger
|--------------------------------------------------------------------------
|
| Here we will configure the error logger setup for the application which
| is built on top of the wonderful Monolog library. By default we will
| build a basic log file setup which creates a single file for logs.
|
*/

Log::useDailyFiles(storage_path().'/logs/laravel-'.get_current_user().'.log');

หากคุณwww ข้อมูลstorage/logs/laravel-www-data-2015-4-27.logผู้ใช้จะสร้างบันทึกข้อผิดพลาดก็จะส่งผลในการ:

หากรากstorage/logs/laravel-root-2015-4-27.logใช้เป็นในการสร้างบันทึกข้อผิดพลาดก็จะส่งผลในการ:

โซลูชันที่ 2:

เปลี่ยนบันทึกที่ใช้โดยคำสั่งช่างฝีมือของคุณในสคริปต์ php ของคุณ

ในrun()ฟังก์ชันของคุณให้เพิ่มบรรทัดนี้เมื่อเริ่มต้น:

Log::useFiles(storage_path().'/logs/laravel-'.__CLASS__.'-'.Carbon::now()->format('Y-m-d').'.log');

หากชื่อชั้นเรียนของคุณคือArtisanRunnerไฟล์บันทึกของคุณจะเป็น:

storage/logs/laravel-ArtisanRunner-2015-4-27.log.

สรุป:โซลูชันหมายเลข 1 ดีกว่าเนื่องจากจะแยกรายละเอียดบันทึกของคุณตามผู้ใช้และด้วยเหตุนี้จึงไม่มีข้อผิดพลาดเกิดขึ้น

แก้ไข: ตามที่เจสันชี้ไว้ให้get_current_user()ส่งคืนชื่อเจ้าของสคริปต์ ดังนั้นสำหรับโซลูชันหมายเลข 1 ที่จะนำไปใช้chownไฟล์คลาสช่างฝีมือของคุณไปยังชื่อผู้ใช้ที่ต้องการ


12
โปรดทราบว่าget_current_user()ส่งคืนเจ้าของสคริปต์ PHP ปัจจุบัน (ตาม php.net) ไม่ใช่ผู้ใช้ที่กำลังเรียกใช้สคริปต์ ฉันใช้php_sapi_name()แทนซึ่งให้ชื่อของ php handler (เช่น apache หรือ cli เป็นต้น) ซึ่งมักจะเรียกใช้เป็นผู้ใช้ที่แตกต่างกัน
Jason

1
ฉันสามารถให้คำแนะนำในการใช้ทั้งชื่อผู้ใช้ที่เรียกใช้สคริปต์และ php_sapi_name ร่วมกันได้หรือไม่เนื่องจากเป็นไปได้สำหรับผู้ใช้จำนวนมากในการเรียกใช้ Laravel จาก CLI เช่น DBA สองสามตัวเข้าถึงเซิร์ฟเวอร์ของคุณหรือคุณอาจต้องการให้ Laravel CRON ทำงานเป็น apache คุณสามารถ รับชื่อกระบวนการที่เรียกใช้สคริปต์นี้โดยใช้ posix_getpwuid (posix_geteuid ()) ['name']; ดูโพสต์ทั้งหมดของฉันด้านล่าง
Andrew

สิ่งนี้จำเป็นต้องได้รับการอัปเดตสำหรับ Laravel เวอร์ชันล่าสุด: v5 +
Andrew

107

Laravel เวอร์ชัน 5.6.10 และใหม่กว่ามีการสนับสนุนpermissionองค์ประกอบในการกำหนดค่า ( config/logging.php) สำหรับsingleและdailyไดรเวอร์:

    'daily' => [
        'driver' => 'daily',
        'path' => storage_path('logs/laravel.log'),
        'level' => 'debug',
        'days' => 7,
        'permission' => 0664,
    ],

ไม่จำเป็นต้องเล่นกลกับ Monolog ในสคริปต์ bootstrap

โดยเฉพาะการสนับสนุนที่ถูกเพิ่มเข้ามาในhttps://github.com/laravel/framework/commit/4d31633dca9594c9121afbbaa0190210de28fed8


9
สิ่งนี้ควรอยู่ในเอกสารอย่างเป็นทางการ!
odupont

3
คำตอบนี้ไม่มีเครื่องหมายอะพอสทรอฟี ควรเป็น 'permission' => '0664' แล้วคำตอบนี้ก็สมบูรณ์ดี!
ฟิล

2
@Phil Nope - นี่เป็นเพียง Wrapper สำหรับ Monologs stream handler ซึ่งยอมรับ int สำหรับสิทธิ์ Monolog ห่อphp.net/manual/en/function.chmod.php - โปรดทราบว่าต้องใช้ 0 นำหน้าเพื่อให้แน่ใจว่าเป็นค่าฐานแปด
คริส

7
'permission' => 0664ใช้ได้กับฉัน (ไม่มีคำพูด)
Syclone

2
@Friedrich หากไฟล์บันทึกของคุณถูกสร้างขึ้นโดยมี 'root' เป็นเจ้าของไฟล์นั่นอาจเป็นสัญญาณว่าคุณมีปัญหาใหญ่กว่าในแง่ของการตั้งค่าเว็บเซิร์ฟเวอร์ของคุณ
kjones

62

สำหรับ Laravel 5.1 ฉันใช้สิ่งต่อไปนี้ที่ด้านล่างของbootstrap/app.php(ตามที่กล่าวไว้ในเอกสาร ):

/**
 * Configure Monolog.
 */
$app->configureMonologUsing(function(Monolog\Logger $monolog) {
    $filename = storage_path('logs/laravel-'.php_sapi_name().'.log');
    $handler = new Monolog\Handler\RotatingFileHandler($filename);
    $monolog->pushHandler($handler);
});

มีเครื่องจัดการอื่น ๆ อีกมากมายที่คุณสามารถใช้แทนได้


1
ฉันชอบคำตอบนี้มากเพราะ 1) อัปเดตเป็น 5.1 และ 2) ใช้วิธีการในเอกสารเพื่อขยายพฤติกรรมการบันทึก
Dylan Pierce

ยอดเยี่ยมไม่จำเป็นต้องใช้แฟลชเดินหน้าเสริม แต่ก็ยังใช้งานได้ ควรอ่าน ... $ filename = storage_path ('logs / laravel -'. php_sapi_name (). '. log');
Andrew

ฉันสามารถให้คำแนะนำในการใช้ทั้งชื่อผู้ใช้ที่เรียกใช้สคริปต์และ php_sapi_name ร่วมกันได้หรือไม่เนื่องจากเป็นไปได้สำหรับผู้ใช้จำนวนมากในการเรียกใช้ Laravel จาก CLI เช่น DBA สองสามตัวเข้าถึงเซิร์ฟเวอร์ของคุณหรือคุณอาจต้องการให้ Laravel CRON ทำงานเป็น apache คุณสามารถ รับชื่อกระบวนการที่เรียกใช้สคริปต์นี้โดยใช้ posix_getpwuid (posix_geteuid ()) ['name']; ดูโพสต์ทั้งหมดของฉันด้านล่าง
Andrew

1
วิธีใช้ใน Laravel 5.6? เนื่องจาก Laravel 5.6 มีระบบ Logging ใหม่ล่าสุด
Hamed Kamrava

26

เพื่อวัตถุประสงค์ดังกล่าวคุณควรใช้ ACL ขั้นสูงกับไฟล์และไดเรกทอรีของคุณ setfaclจะเป็นคำตอบของคุณที่นี่ หากคุณต้องการให้สิทธิ์ผู้ใช้www-dataเขียนบนไฟล์ของ rootในไดเร็กทอรีเฉพาะคุณสามารถทำได้ดังนี้:

setfacl -d -m default:www-data:you-chosen-group:rwx /my/folder

หลังจากออกสิ่งนี้คุณกำลังตั้งค่าการอนุญาตrwxสำหรับผู้ใช้www-dataในไฟล์ทั้งหมด/my/folder/ไม่ว่าใครจะเป็นผู้สร้างก็ตาม โปรดดูสิ่งนี้และคำถามนี้เพื่อเป็นข้อมูลอ้างอิง นอกจากนี้คุณยังสามารถตรวจสอบเอกสารสำหรับsetfacl

โปรดแจ้งให้เราทราบหากสิ่งนี้ช่วยได้


3
คำสั่งต่อไปนี้ใช้ได้ผลสำหรับฉัน: setfacl -d -m g:www-data:rw /full/path/to/laravel/storage/logsตามด้วยphp artisan cache:clearและ composer dump-autoload.
Sawny

17

ฉันได้ผลวิธีง่ายๆ:

ฉันพบปัญหาเดียวกันในLaravel 5.6

ในconfig/logging.phpฉันเพิ่งอัปเดตค่าเส้นทางของช่องรายวันด้วยphp_sapi_name()ในนั้น

สิ่งนี้จะสร้างเอกสารแยกต่างหากสำหรับ php_sapi_name ที่แตกต่างกันและวางไฟล์บันทึกที่มีการประทับเวลาลงในไดเร็กทอรี perticular

'daily' => [
            'driver' => 'daily',
            'path' => storage_path('logs/' . php_sapi_name() . '/laravel.log'),
            'level' => 'debug',
            'days' => 7,
        ]

สำหรับฉัน

  • ไฟล์บันทึกถูกสร้างขึ้นภายใต้fpm-fcgiไดเร็กทอรี: บันทึกจากเว็บไซต์owner: www-data
  • ไฟล์บันทึกถูกสร้างขึ้นภายใต้cliไดเร็กทอรี: จากคำสั่ง artisan (cronjob)owner: root

ข้อมูลเพิ่มเติมเกี่ยวกับการบันทึก Laravel 5.6: https://laravel.com/docs/5.6/logging

นี่คือconfig/logging.phpไฟล์ของฉัน:

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Default Log Channel
    |--------------------------------------------------------------------------
    |
    | This option defines the default log channel that gets used when writing
    | messages to the logs. The name specified in this option should match
    | one of the channels defined in the "channels" configuration array.
    |
    */
    'default' => env('LOG_CHANNEL', 'stack'),
    /*
    |--------------------------------------------------------------------------
    | Log Channels
    |--------------------------------------------------------------------------
    |
    | Here you may configure the log channels for your application. Out of
    | the box, Laravel uses the Monolog PHP logging library. This gives
    | you a variety of powerful log handlers / formatters to utilize.
    |
    | Available Drivers: "single", "daily", "slack", "syslog",
    |                    "errorlog", "custom", "stack"
    |
    */
    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['daily'],
        ],
        'single' => [
            'driver' => 'single',
            'path' => storage_path('logs/laravel.log'),
            'level' => 'debug',
        ],
        'daily' => [
            'driver' => 'daily',
            'path' => storage_path('logs/' . php_sapi_name() . '/laravel.log'),
            'level' => 'debug',
            'days' => 7,
        ],
        'slack' => [
            'driver' => 'slack',
            'url' => env('LOG_SLACK_WEBHOOK_URL'),
            'username' => 'Laravel Log',
            'level' => 'critical',
        ],
        'syslog' => [
            'driver' => 'syslog',
            'level' => 'debug',
        ],
        'errorlog' => [
            'driver' => 'errorlog',
            'level' => 'debug',
        ],
    ],
];

ดี ... ทางออกของคุณสะอาดกว่า .. ฉันกำลังทดสอบเดี๋ยวนี้
Sina Miandashti

1
ดังที่ได้ระบุไว้ในความคิดเห็นอื่นบันทึกเป็นเพียงส่วนหนึ่งของเรื่องราว มีมุมมองที่คอมไพล์แคชข้อมูลซอร์สโค้ดที่แคชไว้ล่วงหน้าซึ่งสิ่งใด ๆ ที่ฉันสร้างขึ้นเป็นไฟล์ในเครื่องโดยเว็บหรือผู้ใช้ cli
Jason

2
สิ่งนี้จะใช้ไม่ได้หากคุณใช้การกำหนดค่าแคชartisan config:cacheเนื่องจากจะสร้างแคชการกำหนดค่าโดยใช้ cli SAPI ซึ่งจะใช้สำหรับคำขอ CLI และเว็บ
leeb

1
สิ่งนี้ใช้ได้ผลสำหรับฉันการพยายามget_current_userไม่ได้ผล แต่ได้php_sapi_nameผล (แม้ว่ามันจะดูน่าเกลียด)
Richard Fu

ฉันคิดว่านี่เป็นวิธีที่เร็วและดีที่สุด การแก้ไขการกำหนดค่าไม่ได้แก้ไขโครงสร้างพื้นฐานของ Laravel เพียงแค่การกำหนดค่า
William Prigol Lopes

13

สำหรับฉันปัญหานี้มากกว่าสิทธิ์ในการบันทึก ... ฉันมีปัญหากับสิ่งที่เกี่ยวข้องกับโฟลเดอร์ bootstrap / cache และ storage ที่ผู้ใช้รายหนึ่งจะสร้างไฟล์ / โฟลเดอร์และอีกคนจะไม่สามารถแก้ไข / ลบได้เนื่องจากมาตรฐาน 644 และ 755 สิทธิ์

สถานการณ์โดยทั่วไปคือ:

  • ไฟล์ bootstrap / cache / compile.php ถูกสร้างโดยผู้ใช้ apache แต่ผู้ใช้ comper ไม่สามารถแก้ไขได้เมื่อดำเนินการคำสั่ง comper install

  • ผู้ใช้ apache สร้างแคชซึ่งไม่สามารถล้างได้โดยใช้ผู้ใช้คอมโพสิต

  • เงื่อนไขการแข่งขันล็อกที่น่ากลัวที่อธิบายไว้ข้างต้น

ความฝันคือไม่ว่าผู้ใช้จะสร้างไฟล์ / โฟลเดอร์ใดผู้ใช้รายอื่นที่ต้องการเข้าถึงจะมีสิทธิ์เหมือนกับผู้เขียนต้นฉบับทุกประการ

TL; DR?

นี่คือวิธีการทำ

เราจำเป็นต้องสร้างกลุ่มผู้ใช้ที่ใช้ร่วมกันที่เรียกว่า laravel กลุ่มนี้ประกอบด้วยผู้ใช้ทั้งหมดที่ต้องการเข้าถึงที่เก็บข้อมูลและไดเรกทอรี bootstrap / แคช ต่อไปเราต้องตรวจสอบให้แน่ใจว่าไฟล์และโฟลเดอร์ที่สร้างขึ้นใหม่มีสิทธิ์กลุ่ม laravel และ 664 และ 775 ตามลำดับ

ทำได้ง่ายสำหรับไฟล์ / ไดเรกทอรีที่มีอยู่ แต่ต้องใช้เวทมนตร์เล็กน้อยในการปรับแต่งกฎการสร้างไฟล์ / โฟลเดอร์เริ่มต้น ...

## create user group
sudo groupadd laravel

## add composer user to group
sudo gpasswd -a composer-user laravel

## add web server to group
sudo gpasswd -a apache laravel

## jump to laravel path
sudo cd /path/to/your/beautiful/laravel-application

## optional: temporary disable any daemons that may read/write files/folders
## For example Apache & Queues

## optional: if you've been playing around with permissions
## consider resetting all files and directories to the default
sudo find ./ -type d -exec chmod 755 {} \;
sudo find ./ -type f -exec chmod 644 {} \;

## give users part of the laravel group the standard RW and RWX
## permissions for the existing files and folders respectively
sudo chown -R :laravel ./storage
sudo chown -R :laravel ./bootstrap/cache
sudo find ./storage -type d -exec chmod 775 {} \;
sudo find ./bootstrap/cache -type d -exec chmod 775 {} \;
sudo find ./storage -type f -exec chmod 664 {} \;
sudo find ./bootstrap/cache -type f -exec chmod 664 {} \;


## give the newly created files/directories the group of the parent directory 
## e.g. the laravel group
sudo find ./bootstrap/cache -type d -exec chmod g+s {} \;
sudo find ./storage -type d -exec chmod g+s {} \;

## let newly created files/directories inherit the default owner 
## permissions up to maximum permission of rwx e.g. new files get 664, 
## folders get 775
sudo setfacl -R -d -m g::rwx ./storage
sudo setfacl -R -d -m g::rwx ./bootstrap/cache

## Reboot so group file permissions refresh (required on Debian and Centos)
sudo shutdown now -r

## optional: enable any daemons we disabled like Apache & Queues

เพื่อวัตถุประสงค์ในการดีบักเท่านั้นฉันพบว่าการแยกล็อกออกเป็นผู้ใช้ทั้ง cli / web + มีประโยชน์ดังนั้นฉันจึงแก้ไขคำตอบของ Sam Wilson เล็กน้อย กรณีการใช้งานของฉันคือคิวที่รันภายใต้ผู้ใช้ของตัวเองดังนั้นจึงช่วยแยกความแตกต่างระหว่างผู้ใช้คอมโพสิตโดยใช้ cli (เช่นการทดสอบยูนิต) และคิวดีมอน

$app->configureMonologUsing(function(MonologLogger $monolog) {
     $processUser = posix_getpwuid(posix_geteuid());
     $processName= $processUser['name'];

     $filename = storage_path('logs/laravel-'.php_sapi_name().'-'.$processName.'.log');
     $handler = new MonologHandlerRotatingFileHandler($filename);
     $monolog->pushHandler($handler);
}); 

เรื่องนี้ดีมาก configureMonologUsingรหัสของคุณยังจำเป็นอยู่หรือไม่เมื่อคุณเรียกใช้setfaclคำสั่ง
jeff-h

7

ลาราเวล 5.1

ในกรณีของเราเราต้องการสร้างไฟล์บันทึกทั้งหมดเพื่อให้ทุกอย่างในdeployกลุ่มมีสิทธิ์อ่าน / เขียน ดังนั้นเราจึงจำเป็นต้องสร้างไฟล์ใหม่ทั้งหมดที่มี0664สิทธิ์ซึ่งตรงข้ามกับ0644ค่าเริ่มต้น

เรายังได้เพิ่มฟอร์แมตเตอร์เพื่อเพิ่มบรรทัดใหม่เพื่อให้อ่านง่ายขึ้น:

$app->configureMonologUsing(function(Monolog\Logger $monolog) {
    $filename = storage_path('/logs/laravel.log');
    $handler = new Monolog\Handler\RotatingFileHandler($filename, 0, \Monolog\Logger::DEBUG, true, 0664);
    $handler->setFormatter(new \Monolog\Formatter\LineFormatter(null, null, true, true));
    $monolog->pushHandler($handler);
});

นอกจากนี้ยังสามารถรวมสิ่งนี้กับคำตอบที่ยอมรับได้

$app->configureMonologUsing(function(Monolog\Logger $monolog) {
    $filename = storage_path('/logs/laravel-' . php_sapi_name() . '.log');
    $handler = new Monolog\Handler\RotatingFileHandler($filename, 0, \Monolog\Logger::DEBUG, true, 0664);
    $handler->setFormatter(new \Monolog\Formatter\LineFormatter(null, null, true, true));
    $monolog->pushHandler($handler);
});

6

วิธีหนึ่งที่ไม่ใช่ Laravel ในการทำให้งานนี้คือการดำเนินการ cronjob ของคุณเป็น www-data

เช่น/ubuntu/189189/how-to-run-crontab-as-userwww-data

/etc/crontab

*/5 * * * * www-data php /var/www/public/voto_m/artisan top >/dev/null 2>&1


5

ลาราเวล 5.5

เพิ่มรหัสนี้ในbootstrap/app.php:

$app->configureMonologUsing(function (Monolog\Logger $monolog) {
    $filename = storage_path('logs/' . php_sapi_name() . '-' . posix_getpwuid(posix_geteuid())['name'] . '.log');
    $monolog->pushHandler($handler = new Monolog\Handler\RotatingFileHandler($filename, 30));
    $handler->setFilenameFormat('laravel-{date}-{filename}', 'Y-m-d');
    $formatter = new \Monolog\Formatter\LineFormatter(null, null, true, true);
    $formatter->includeStacktraces();
    $handler->setFormatter($formatter);
});
  • มันจะจัดเก็บไฟล์ในลักษณะนี้: laravel-2018-01-27-cli-raph.logและlaravel-2018-01-27-fpm-cgi-raph.logอ่านได้มากขึ้น
  • บรรทัดใหม่จะถูกรักษาไว้ (ตามพฤติกรรม Laravel เริ่มต้น)
  • ทำงานร่วมกับLaravel Log Viewer

ลาราเวล 5.6

คุณต้องสร้างคลาสสำหรับคนตัดไม้ของคุณ:

<?php

namespace App;

use Monolog\Logger as MonologLogger;

class Logger {
    public function __invoke(array $config)
    {
        $monolog = new MonologLogger('my-logger');
        $filename = storage_path('logs/' . php_sapi_name() . '-' . posix_getpwuid(posix_geteuid())['name'] . '.log');
        $monolog->pushHandler($handler = new \Monolog\Handler\RotatingFileHandler($filename, 30));
        $handler->setFilenameFormat('laravel-{date}-{filename}', 'Y-m-d');
        $formatter = new \Monolog\Formatter\LineFormatter(null, null, true, true);
        $formatter->includeStacktraces();
        $handler->setFormatter($formatter);
        return $monolog;
    }
}

จากนั้นคุณต้องลงทะเบียนในconfig/logging.php:

'channels' => [
    'custom' => [
        'driver' => 'custom',
        'via' => App\Logging\CreateCustomLogger::class,
    ],
],

ลักษณะการทำงานเช่นเดียวกับ 5.5:

  • มันจะจัดเก็บไฟล์ในลักษณะนี้: laravel-2018-01-27-cli-raph.logและlaravel-2018-01-27-fpm-cgi-raph.logอ่านได้มากขึ้น
  • บรรทัดใหม่จะถูกรักษาไว้ (ตามพฤติกรรม Laravel เริ่มต้น)
  • ทำงานร่วมกับLaravel Log Viewer

ตอบดีที่สุด! Kudos
Shahid Karimi

4

เพิ่มสิ่งต่อไปนี้ที่จุดเริ่มต้นของapp/start/artisan.phpไฟล์ของคุณ(ใช้กับ Laravel 4):

// If effectively root, touch the log file and make sure it belongs to www-data
if (posix_geteuid() === 0) {
    $file = storage_path() . '/logs/laravel.log';
    touch($file);
    chown($file, 'www-data');
    chgrp($file, 'www-data');
    chmod($file, 0664);
}

ปรับเส้นทางหากไฟล์บันทึกรายวันที่คุณกล่าวถึงไม่ใช่ไฟล์บันทึก Laravel มาตรฐาน คุณอาจไม่ต้องการเปลี่ยนกลุ่มหรือตั้งค่าการอนุญาตเหมือนที่ฉันทำอยู่ที่นี่ ข้างต้นตั้งค่ากลุ่มwww-dataและตั้งค่าสิทธิ์การเขียนกลุ่ม จากนั้นฉันได้เพิ่มผู้ใช้ประจำของฉันลงในwww-dataกลุ่มเพื่อให้เรียกใช้คำสั่งช่างฝีมือในฐานะผู้ใช้ทั่วไปของฉันยังคงสามารถเขียนลงในบันทึกได้

การปรับแต่งที่เกี่ยวข้องคือการใส่สิ่งต่อไปนี้ที่จุดเริ่มต้นของapp/start/global.phpไฟล์ของคุณ:

umask(0002);

หากคุณทำเช่นนี้chmodบรรทัดด้านบนจะกลายเป็นสงสัย เมื่อตั้งค่า umask เป็นไฟล์ใหม่ PHP (และด้วยเหตุนี้ Laravel) จะทำให้สิทธิ์ของพวกเขาถูกปิดบังไว้เท่านั้นเพื่อไม่ให้ผู้ใช้ "รายอื่น" ไม่มีสิทธิ์ในการเขียน ซึ่งหมายความว่าไดเรกทอรีจะเริ่มต้นและเป็นไฟล์rwxrwxr-x rw-rw-r--ดังนั้นหากwww-dataใช้ PHP แคชและไฟล์บันทึกใด ๆ ที่สร้างขึ้นจะสามารถเขียนได้โดยค่าเริ่มต้นโดยทุกคนในกลุ่มหลักของผู้ใช้ซึ่งก็คือwww-data.


4

(Laravel 5.6) เมื่อเร็ว ๆ /app/Console/Kernel.phpนี้ผมวิ่งเข้าไปในปัญหาเดียวกันและผมก็ตั้งค่าคำสั่งที่กำหนดให้ทำงานใน

$schedule->exec('chown -R www-data:www-data /var/www/**********/storage/logs')->everyMinute();

ฉันรู้ว่ามันเกินความจริงไปหน่อย แต่มันใช้งานได้ดีและไม่มีปัญหาใด ๆ เลยตั้งแต่นั้นมา


มันได้ผล ? ใช่ แต่แนวทางปฏิบัติที่ดีที่สุดคืออะไร? ผมคิดว่าไม่.
Pablo Papalardo

3

ลาราเวล 5.4

\Log::getMonolog()->popHandler(); \Log::useDailyFiles(storage_path('/logs/laravel-').get_current_user().'.log');

เพิ่มbootฟังก์ชันในAppServiceProvider


1

ลาราเวล 5.8

Laravel 5.8 config/logging.phpช่วยให้คุณตั้งชื่อบันทึกใน

ดังนั้นการใช้คำตอบและความคิดเห็นก่อนหน้านี้หากคุณต้องการตั้งชื่อบันทึกโดยใช้ทั้งชื่อผู้ใช้ posix จริงและphp_sapi_name()ค่าคุณจะต้องเปลี่ยนชุดชื่อบันทึกเท่านั้น การใช้โปรแกรมควบคุมรายวันช่วยให้สามารถหมุนเวียนบันทึกที่ทำงานต่อชุดค่าผสมของผู้ใช้ / api ซึ่งจะช่วยให้มั่นใจได้ว่าบันทึกจะถูกหมุนเวียนโดยบัญชีที่สามารถแก้ไขบันทึกได้เสมอ

ฉันยังได้เพิ่มการตรวจสอบฟังก์ชัน posix ซึ่งอาจไม่มีอยู่ในสภาพแวดล้อมโลคัลของคุณซึ่งในกรณีนี้ชื่อบันทึกจะเป็นค่าเริ่มต้นเป็นมาตรฐาน

สมมติว่าคุณใช้ช่องบันทึกเริ่มต้น "รายวัน" คุณสามารถแก้ไขคีย์ "ช่อง" ได้ดังนี้:

# config/logging.php
'channels' => [
    ...
    'daily' => [
        'driver' => 'daily',
        'path'   => storage_path(
            function_exists('posix_getpwuid') 
            && function_exists('posix_geteuid')
                ? 'logs/laravel'
                    . '-' . php_sapi_name()
                    . '-' . posix_getpwuid(posix_geteuid())['name'] 
                    . '.log'
                : 'logs/laravel.log'),
        'level'  => 'debug',
        'days'   => 15,
    ],
    ...

ซึ่งจะส่งผลให้ชื่อบันทึกควรไม่ซ้ำกันสำหรับแต่ละชุดค่าผสมเช่นlaravel-cli-sfscs-2019-05-15.logหรือlaravel-apache2handler-apache-2019-05-15.logขึ้นอยู่กับจุดเชื่อมต่อของคุณ


0

คุณสามารถเปลี่ยนสิทธิ์ของไฟล์บันทึกในคำสั่งช่างฝีมือของคุณ:

$path = storage_path('log/daily.log');
chown($path, get_current_user());

โดยที่get_current_user ()จะส่งกลับผู้ใช้ของสคริปต์ปัจจุบัน

กล่าวอีกนัยหนึ่งdaily.logจะมีwww-dataเป็นเจ้าของเสมอแม้ว่าคุณจะเริ่มต้นสคริปต์ในฐานะrootผู้ใช้ก็ตาม


0

หากคุณใช้Laravel Envoyerนี่คือวิธีแก้ไขที่เป็นไปได้โดยใช้ ACL ใน Linux:

1. ขั้นแรกเรียกใช้สคริปต์ต่อไปนี้ด้วยrootสิทธิ์บนเซิร์ฟเวอร์:

ในทั้งสองสคริปต์คุณจะต้องแทนที่ตัวแปรตามคำแนะนำด้านล่าง:

  • {{MASTER_PATH}} : เส้นทางไปยังไดเรกทอรีโฮสต์เสมือนของคุณ (เช่นโฟลเดอร์> ที่มีแอปพลิเคชันของคุณ)
  • {{WEB_SERVER_USER}} : ผู้ใช้ที่เว็บเซิร์ฟเวอร์ของคุณใช้
  • {{DEPLOYMENT_USER}} : ผู้ใช้สคริปต์การปรับใช้ของคุณถูกเรียกใช้
#!/bin/bash

DIRS="storage current/bootstrap/cache"
MASTER_PATH={{MASTER_PATH}}

if [ -d $MASTER_PATH ]; then 
    cd $MASTER_PATH
    for p in `ls $MASTER_PATH`; do 
        if [ -d $MASTER_PATH/$p ]; then     
        cd $MASTER_PATH/$p
            echo "Project: $p -> $MASTER_PATH/$p"
            for i in $DIRS; do 
                echo "- directory: $i" 
                if [ -d $i ]; then 
                    echo "-- checking ACL..."
                    HAS_ACL=`getfacl -p $i | grep "^user:{{WEB_SERVER_USER}}:.*w" | wc -l`
                    if [  $HAS_ACL -eq 0 ]; then 
                        echo "--- applying $i"
                        setfacl -L -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
                        setfacl -dL -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
                    else
                        echo "--- skipping $i"
                    fi
                fi
            done
        echo "--------------"
        fi
    done
else
    echo "No $MASTER_PATH - skipping overall"
fi

2. ตั้งค่า hook สำหรับการปรับใช้ต่อไปนี้กับ envoyer ภายใต้ "Activate New Release"> "Before This Action

PROJECT_DIRS="storage"
RELEASE_DIRS="bootstrap/cache"
 
cd {{ project }}
 
for i in $PROJECT_DIRS; do
  if [ -d $i ]; then
    HAS_ACL=`getfacl -p $i | grep "^user:{{WEB_SERVER_USER}}:.*w" | wc -l`
    if [  $HAS_ACL -eq 0 ]; then
      echo "ACL set for directory {{project}}/$i"
      setfacl -L -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
      setfacl -dL -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
    fi
  fi
done
 
cd {{ release }}
 
for i in $RELEASE_DIRS; do
  if [ -d $i ]; then
    HAS_ACL=`getfacl -p $i | grep "^user:{{WEB_SERVER_USER}}:.*w" | wc -l`
    if [  $HAS_ACL -eq 0 ]; then
      echo "ACL set for directory {{project}}/$i"
      setfacl -L -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
      setfacl -dL -R -m u:{{WEB_SERVER_USER}}:rwX -m u:{{DEPLOYMENT_USER}}:rwX $i
    fi
  fi
done

3. ปรับใช้แอปพลิเคชันของคุณอีกครั้ง

ตอนนี้ปรับใช้แอปพลิเคชันของคุณอีกครั้งและควรดำเนินการต่อไป

หมายเหตุ: ควรเรียกใช้สคริปต์ที่กำหนดใน1.ทุกครั้งที่คุณเพิ่มโปรเจ็กต์ใหม่ลงในเครื่อง



-1

วิธีที่ดีที่สุดที่ฉันพบคือ fideloper แนะนำhttp://fideloper.com/laravel-log-file-nameคุณสามารถตั้งค่าการบันทึก laravel โดยไม่ต้องแตะคลาส Log ฉันคิดว่ามีชื่อแตกต่างกันสำหรับโปรแกรม Console และโปรแกรม Http เป็นทางออกที่ดีที่สุด


-1

โซลูชันนี้จะใช้ได้กับ Laravel V5.1 - V6.x อย่างแน่นอน

สาเหตุของข้อผิดพลาดนี้:

  • สาเหตุหลักมาจากปัญหาการอนุญาต
  • ไม่พบตัวแปรสภาพแวดล้อมหรือ.envไม่พบไฟล์บนไดเร็กทอรีรากของคุณ
  • ปัญหาส่วนขยาย PHP
  • ปัญหาฐานข้อมูล

แก้ไข:

  • ตั้งค่าการอนุญาตที่ถูกต้อง:
    • เรียกใช้คำสั่งเหล่านี้ (Ubuntu / Debian)
find /path/to/your/root/dir/ -type f -exec chmod 644 {} \;
find /path/to/your/root/dir/ -type d -exec chmod 755 {} \;

chown -R www-data:www-data /path/to/your/root/dir/

chgrp -R www-data storage bootstrap/cache
chmod -R ug+rwx storage bootstrap/cache
  • หากไม่มีไฟล์. envให้สร้างทีละไฟล์touch .envและวางตัวแปรสภาพแวดล้อมของคุณแล้วเรียกใช้
   php artisan key:generate
   php artisan cache:clear
   php artisan config:clear
   composer dump-autoload
   php artisan migrate //only if not already migrated
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.