라라벨 프로젝트 5 – 조아로그

다음 할 것은 이걸모아서 보고 싶다. 조아로그를 만드는 이유는 당시 내가 좋았던 경험을 기록해서 그걸 강화하기 위함이다. 뭐가 됐든. 그러니 이걸 모아서 볼 수 있는 장치가 필요하다.

처음으로 떠오른건 달력형태의 뷰였다. 그런데 이건 모아보는 용도는 아니다. 단지 클릭해서 그날의 정보를 보는 역할만 한다. 그게 나쁜건 아닌데 뭔가 아쉽다. 좀더 내가 작성한 내용을 모아서 보고 싶다.

일주일을 하나의 단위로 해서 스프린트형태로 만들어봤다. 이렇게 하니 그 주에 있었던 일, 좋았던 것들을 한 눈에 볼 수 있어 좋았다.

라라벨 프로젝트 4 – 조아로그, 프로필사진

jetstream에는 profile사진이 있는데 이거 80포트 이외에는 작동하지 않는다. 이유는 포트포워딩이 profile photo엔 적용되어있지 않기때문.

브라우저에서 8080으로 요청을 하더라도 html코드에서는 별도로 80포트로 image를 요청하기 때문에 포트포워딩이 되지 않는다.

아니 말이 안되는데?

라라벨 프로젝트 – 조아로그 3

지난번엔 인증을 breeze로 했는데 이번엔 jetstream으로 할 예정

sail에 한 번 적응하고나선 다르게는 못하겠다. 이거 너무 편하다.

jetstream은 인증만 있는게 아니라 인증백엔드는 fortify가 하고 프론트만 jetstream으로 하는거 같아.

생각해보니 oauth2로 구글연동을 해야 사용자입장에서 편하게 로그인을 할거같아.

oauth2는 passport로 연동.

이 과정이 참 길겠다.

라라벨 프로젝트 – 일상메모 2 (why)

메인 화면은 최대한 깔끔하게 입력 폼과 전송 버튼 딱 두 개로 되어있다.

두 번째 화면은 지금까지 입력한 내용을 일별로 시간순서대로 볼 수 있다. 여기서 주간을 선택하면 주간만 볼 수 있다. 월을 선택하면 달력형태로 볼 수 있다. (이런건 나중에 해도 되는데)

시간 순서대로라 함은 아래로 표시되는데 이때 비어있는 시간도 그대로 노출한다. 단지 카드형태로 순서대로 나오는게 아니라 언제 등록했는지 문자만이 아니라 모양으로 인식할 수 있게 하면 좋겠다. 이건 직접 보고나서 결정하기로 한다.(이것도 그렇고)

이 프로젝트의 목표는 기록을 통해 나를 발견한다. 나는 나에대해 얼마나 알고 있나? 나를 알고나서 내가 무슨 생각을 하는지 알고나서 나의 강점, 약점을 파악하여 장점을 잘 살릴수 있도록 도움을 주고자 이 앱을 만든다. AI를 도입하여 나의 성격 및 좋아하는 것을 파악한다. (ai까지는 오바이고 우선 내가 좋아하는걸 찾는게 급선무이다. 나는 생각이 휘발되어 뭘 좋아하는지 생각하려면 다 잊어버리기 때문에)

그래 좋아하는것. 일상 메모를 통해 나를 발견한다. 나를 발견하여 내가 뭘 하면 좋을지 알아낸다. 이걸로 제2의 직업을 찾을 수도 있고, 좋아하는 일을 시작할 수도 있다. 회사에서는 적성에 맞는 사람을 찾을 수 있다. 그러려면 공신력이 있어야겠지(이것도 너무 나갔다.)

좋았던 것들을 기록한다!

라라벨 프로젝트 – 일상메모

라라벨로 뭘 하면 좋을지 생각을 해봤다. 웹서비스 전반을 할 수 있긴 한데 이렇게 MVC가 명확하고 React나 Vue와의 연동이 수월하면 웹앱이 좋은데.

그때그때 생각을 기록하는걸 만들어보자. 노션을 사용해도 좋은데 그건내가 원하는 모양이 아니다

내가 원하는 모양은 언제든지 입력할 수 있고 이 입력은 자동으로 해당 시간대에 기록이 되며 원하면 언제든지 일별로 리스트형태로 해서 몇시 몇분에 어떤 기록을 했는지 확인 할 수 있어야 한다. 이걸 원하는 이유는 김익한 교수님의 가르침을 현실에 적용하기 위한 방법이다. 감정을 기록하여 나에대해 좀더 정확하게 알기위해서이다.

일상의 메모.

이부분을 좀더 다듬어보자.

라라벨 시작하기 14 – 배포

코드 작업이 끝나면 배포을 하여 세상에 나의 코드를 적용시키는 과정을 거쳐야 한다. 그런데 이 과정이 상당히 까다롭다. 배포시 고려해야할 사항이 많기 때문이다.

먼저 시작하기 문서(https://laravel.kr/docs/9.x/installation)를 통해 라라벨 프로젝트를 시작하면 다음과 같은 구조의 파일이 나온다.

curl -s https://laravel.build/example-app | bash

자, 그리고 gitignore에는 이렇게 되어있다.

저장소에는 vendor와 .env를 제외하라고 되어있다. 그 말은 배포서버에서 컴포저 인스톨을 해야 한다는거고 node_modules도 마찬가지이다. 배포 과정에 이것들이 포함되어 있어야 한다는 거다.

필요한건 node, php-fpm, nginx 이 세 가지이다. 설치하고나서 기다리고 있는건 권한문제가 있다. 만약 nginx와 php-fpm을 잘 설치했다면 nginx user는 nginx로 되어있을거고 php-fpm 유저는 www-data로 되어있을거다.

이 두 서비스의 user를 하나로 만들어야 권한문제가 발생하지 않는다. 배포한 소스도 user를 맞추자.

내경우엔 여러 복잡한 사정이 더 포함되어있어 서버에서 해당 서비스를 도커로 진행해야하기에 젠킨스 배포과정이 더 복잡해져서 시간을 많이 잡아먹었다.

오늘은 여기까지.

라라벨 시작하기 13 – Debug

PHP는 Xdebug라는 강력한 툴을 제공한다. 그런데 이거 초반에 많이 헤맸다. 로컬에서는 아무 문제가 없다.

내 경우엔 윈도우에 php를 직접 설치하여 개발을 하지 못했다. PHP버전때문. 회사 프로젝트의 php버전이 낮아 최신 버전을 사용할 수 없었다. 그래서 도커로 예전 버전 이미지를 사용하여 개발을 할 수밖에 없었다. 오히려 이게 깔끔하다. 그런데 이렇게 하니 디버깅을 어떻게 해야 할지 난감했다.

그렇지만 방법을 찾았다.

나는 vscode를 사용하여 개발한다. 여기에 remote explorer 확장이 있다. 이걸로 해당 서버에 원격으로 접속할 수 있다. 그리고 미리 준비된 xdebug가 포함된 php 서버이미지를 사용하여 프로젝트를 시작한다. 라라벨은 이미 준비되어있다.

remote explorer의 Dev Containers에 해당 컨테이너를 선택하여 진입하고 Explorer에서 Open Folder를 선택하여 프로젝트 폴더를 선택한다.

이런 유사한 화면이 나올것이다. 여기서 프로젝트 폴더를 선택한다. 라라벨에선 /var/www/html이다.

그리고 xdebug 설정을 한다.

xdebug_mode는 develop, client_host는 localhost로 했다. idekey=docker는 phpstorm에서 사용한다던데 써본적이 없어 잘 모르겠다.

vscode의 디버깅 툴(Run and Debug)을 사용하자. 처음엔 어떤 디버깅 툴을 사용하려고 하는지 선택하라고 나오는데 PHP를 선택하자.

톱니바퀴 모양을 누르면 launch.json을 만들어줄거다. 자동으로 만들어준다. 설정은 바꾸지 않아도 된다.

이제 저 play버튼을 누르면 서버의 debug port와 연결한다. 이제부터 소스에 브레이크포인트를지정하여 디버깅을 할 수 있다.

알면 별거 아닌데.

오늘은 여기까지.

라라벨 시작하기 12 – 로그

사용하기는 쉽다.

use Illuminate\Support\Facades\Log;

를 상단에 선언해주고 하단에

Log::info('Log');

형태로 작성해주면 된다.

그럼 이렇게 로그가 생긴다.로그로테이트는 daily 채널을 사용하자.

추가로 해당 클래스 또는 함수명을 출력해주도록 하는건 나중에 추가한다.

로그에 함수명, 클래스명을 출력하기

이렇게 하고 싶은 이유는 스프링의 로그가 이렇게 되어있었기 때문이다. 그리고 이렇게 하면 꽤나 도움을 많이 받았다.

CustomFormatter를 만들자

나는 daily 체널을 그대로 활용하고 싶었다. 그리고 최대한 제공하는걸 사용하고 싶어 커스터마이징을 따라서 tab에 포메터를 추가하고 싶었다. 그런데 이게 작동을 하지 않는다. 작동하지 않았던 이유는 마지막에…

하는수 없이 프로바이더에 커스텀로그서비스를 추가하였다.(feat, ChatGPT)

class CustomFormatter implements FormatterInterface {
    public function format($record): string {
        // 디버그 백트레이스에서 클래스와 함수명 추출
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
        $caller = isset($trace[2]) ? $trace[2] : null;
        $class = $caller['class'] ?? 'N/A';
        $function = $caller['function'] ?? 'N/A';

        // 로그 메시지 포맷
        return sprintf(
            "[%s] %s: [%s::%s] %s\n",
            $record['datetime']->format('Y-m-d H:i:s'),
            strtoupper($record['level_name']),
            $class,
            $function,
            $record['message']
        );
    }

    public function formatBatch(array $records): array {
        return array_map([$this, 'format'], $records);
    }
}

그런데 이렇게 하니 문제가 발생. 당연하게도 Logger 그자체를 출력해버림. 이번엔 Logger를 제외한 첫번째 클래스를 찾아서 출력하라고 했더니 별반 다르지 않는 코드를 줬다.

대강 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 6); 3에서 6으로 늘었다. xdebug로 뭘 출력하는지 알아봤다. 전체 stack trace를 출력하는걸 확인했다. 뒤에 숫자는 몇 번째까지 출력하는지 지정하는거였다.

결국 최종 원하는 결과물을 얻을 수 있는 코드는 다음과 같았다.

<?php
namespace App\Logging;

use Monolog\Formatter\FormatterInterface;

class CustomTabFormatter implements FormatterInterface {
    public function format($record): string {
        // 클래스와 함수명을 포함한 로그 메시지 포맷
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 9);
        $caller = isset($trace[8]) ? $trace[8] : null;
        $class = $caller['class'] ?? 'N/A';
        $function = $caller['function'] ?? 'N/A';

        $message = sprintf(
            "[%s] %s\t[%s::%s]\t%s\n",
            $record['datetime']->format('Y-m-d H:i:s'),
            $record['level_name'],
            $class ?? 'N/A',
            $function ?? 'N/A',
            $record['message'],
        );

        return $message;
    }

    public function formatBatch(array $records): array {
        return array_map([$this, 'format'], $records);
    }
}

그런데 이 코드, 성능이슈가 있을 수 있다. debug옵션에서만 쓰던지 해야지.

오늘은 여기까지.

라라벨 시작하기 11 – 노티

라라벨에는 노티가 있다. 이벤트를 등록하고 이를 수신하여 알림으로 메일을 통해 전달하게 예제는 되어있다. 그런데 작동을 안한다. 어디가 문제인지 찾아보자.

일단 로그가 어떻게 돌아가는지 확인하자.

그 전에 개발 순서를 정리하자

이벤트 진행 순서

  1. 노티 생성php artisan make:notification NewChirp
  2. 이벤트 생성 php artisan make:event ChirpCreated
  3. 이벤트 디스패치
  4. 이벤트 리스너 생성 php artisan make:listener SendChirpCreatedNotifications –event=ChirpCreated
  5. 이벤트 리스너 등록

로그

각 부분에 로그를 심었는데 글을 작성하면 이렇게 밖에 찍히지 않는다.

이 부분인데 foreach 안으로 들어오지 못했다.

저게 어떤 쿼리인지 확인하면 좋겠는데…

이제 알았다. 저 노티의 의도를 파악했어야 했는데… 저건 어떤 사람이 글을 작성하면 다른 모든 사람들에게 노티를 보내는 구조로 되어있던 것이다. 그걸 모르고 나는 유저를 하나만 등록하고 메세지를 작성했으니. 아무리 등록을 해도 그걸 받을 사람이 없었던것.

구조를 배울 수 있어 좋았다. 물론 실제 운영에 사용하려면 상당한 커스텀이 들어가야 하겠지만.

오늘은 여기까지.

라라벨 시작하기 10 – 수정하기

입력하기는 해당 데이터를 추가하고 추가된 내용을 화면에 출력하기만 하면 된다. 그런데 수정하기는 좀더 복잡한 과정을 거쳐서 수정을 해야 한다. 누가 입력했는지 어떤걸 입력했는지 확인해야 한다. 그러려면 사용자도 있어야 하고 로그인 기능도 있어야 한다.

먼저 로그인 및 사용자는 Laravel/Bleeze를 사용하고 있다. 그리고 Laravel은 기본적으로 Schema에 timestamps 하나로 created_at과 updated_at을 제공한다.

edited라는 표시를 어떻게 하나 봤더니 created_at과 updated_at이 다르면 표시하게 되어있었다. 그간 나는 updated_at에는 null인 상태, 그러니까 아무것도 입력하지 않은 상태로 유지하고 update가 발생할 경우 입력하여 일시를 기록했는데 최초에 updated_at을 created_at과 함께 입력하여 null을 방지하였을거라 추측한다. 이게 더 합리적이네.

그리고 삭제버튼에 이렇게 폼을 추가하여 넣는다는 발상은 하지 못했는데 하나 배웠다.

오늘은 여기까지.