React + TypeScript 설치(yarn)

React + TypeScript 설치하는 방법으로 npm 을 이용하는 방법이 있다. 하지만 현 시점, 그러니까 React 버전이 19인 경우 경우에는 npm 명령어 설치할 경우에 오류를 만날 수 있다.

React 설치 오류

보통 React 설치를 위해서 다음과 같이 npx 명령어를 사용한다.

하지만 이렇게 할 경우에 현시점에서 다음과 같이 오류가 발생한다.

이에 대한 해결 방법으로 React 18 로 다운그레이드 하면 된다고 글도 많은데, 프로젝트가 React 18 을 요구하지 않을 경우를 제외하고 다운그레이드는 권장하지 않는다.

오류 원인

React 19 로 넘어오면서 의존성 라이브러리가 교체되었다고 한다. React 18 까지는 web-vitals 를 사용했었지만 19로 넘어오면서 vite 를 사용하도록 되었다고 한다. 변경된 라이브러리로 인해서 React 19 설치 명령어도 변경이 있었다.

Yarn 을 이용한 설치

npm 이 버전이 업데이트 되면서 yarn 의 사용이 많이 준 것도 사실이다. 하지만 현 시점에서 React + TypeScrpt 조합과 web-vitals 를 이용하고자 한다면 yarn 을 이용하는 것이 좋다.

yarn 을 글로벌(Global) 로 설치해 준다.

그리고 yarn 을 이용해서 다음과 같이 명령어를 쳐준다.

yarn 을 이용하면 위와 같이 정상적으로 생성이 가능해진다. package.json 파일을 보면 다음과 같다.

의존성 정보를 보면 React 19 와 web-vitals 를 조합해 설치된 것을 알 수 있다.

VSCode 설정

React + TypeScript 설치가 되었다면 프로그래밍을 해야한다. 대부분 VSCode 를 많이 쓰는데, VSCode 에서 제공하는 확장(Extensions) 를 활용하면 많은 이점이 있다. 이에 대해서 간단하게 알아본다.

ESLint

Create 으로 생성된 React 앱에서는 이미 ESLint 가 포함되어 있다. package.json 파일을 열어보면 eslint 관련 설정이 들어 있는 것을 확인할 수 있다.

이것을 VSCode 에디터 차원에서 지원을 할 수 있는데, ESLint 확장을 설치하면 된다.

이것을 설치하고 난 후에 VSCode 에 세팅(Setting) 에서 관련 내용을 추가할 수 있다.

Settings 에서 ‘eslint: probe’ 로 검색 후에 Workspace 탭을 확인하면 되는데, 여기서 javascript 와 typescript, typescriptreact 등이 있으면 된다.

Code Formatting

코드 포맷팅은 아주 중요하다고 할 수 있다. 여러사람이 협업을 하는 현대의 프로그래밍 작업에서 일관된 코드 포맷팅만큼 중요한 건 없다.

Prettier 는 유명한 코드 포맷터이다. React 앱을 생성하더라도 Prettier 는 설치가 되지 않는다. 다음과 같이 설치해 준다.

하지만 이렇게 하면 에러가 발생한다. npx 를 이용해 React 앱을 생성하려고 했던 거와 동일한 에러가 발생한다. yarn 을 이용해 React 앱을 생성했기 때문에 yarn 을 이용해야 한다.

ESLint 도 코드 포맷관련해 기능을 가지고 있다. Prettier 를 설치하면 이 둘이 충돌이 발생할 수 있어서 이를 피하기 위해서 다음의 플러그인도 함께 설치해 준다.

‘eslint-config-prettier’ 는 ESLint Rule 충돌을 방지해주고 ‘eslint-plugin-prettier’ 는 ESLint 에게 코드 포맷터로 Prettier 를 사용하라고 알려준다.

ESLint 설정에서 Prettier 를 사용하도록 설정을 해준다. package.json 파일에 eslintConfig 세션에서 다음과 같이 prettier 설정을 추가해 준다.

Prettier 설정을 위해서 .prettierrc.json 파일을 다음과 같이 생성한다.

소스코드 작성시에 VSCode 에서 이를 활용할 수 있도록 Prettier 확장을 설치한다.

그리고 Settings -> Workspace 탭에서 Format On Save 를 체크 한다.

또, VSCode 의 Default Formatter 를 Prettier 로 변경해 준다.

마치며

React 19 로 넘어오면서 Vite(비트 라고 발음한다. 영어가 아니라 프랑어라고 한다.) 로 변경되었다. 그래서 npx 를 이용해 React 앱을 생성하면 오류가 발생하는데, yarn 을 통해서 React 19 를 사용하면 기본의 컴포넌트 조합을 그대로 사용할 수가 있다.

또, VSCode 와 통합을 위한 플러그인 설치과 설정등도 간단하게 알아 봤다.

React + Typescript 세팅하기(Webpack)

최근에 React + TypeScript 를 배우고 있는데, 생각만큼 잘 되지 않는 부분도 있고 각각의 의미가 다 있는 만큼 한번 정리할 필요가 있어서 글을 쓴다.

React + TypeScript 를 세팅하는 방법에는 두가지가 있다.

  • Webpack 을 이용하기
  • React App 생성하기

여기서는 Webpack 을 이용해 React + TypeScript 세팅을 해볼 것이다.

Webpack 프로젝트 생성

webpack 은 프로젝트 생성 툴이 아니다. webpack 은 React + TypeScript 와 아무런 상관이 없다. 단지 React + TypeScript 생성을 이용할 수 있는 하나의 방법이다.

webpack 은 CSS, JavaScript 등을 모두 생성해 준다. 특징이 있다면 JavaScript 의 경우에는 하나의 파일로 만들어 준다. 여러가지 파일을 만드는 것이 아니라 오직 한개의 파일로 모두 작성된다.

package.json 파일 생성

nodejs 에 프로젝트 정보파일인 package.json 파일을 생성해 준다. 프로젝트 이름, 의존성, npm 스크립트등을 기재하면 할 수 있지만 일단 최소한의 정보만 입력한다.

nodejs 의 의존성 패키지들은 npm 명령어로 설치하면 자동으로 package.json 파일에 기재된다.

web page 추가

src 폴더를 생성하고 그 안에 index.html 파일을 작성한다.

React 가 실행되면서 속성값인 id=”root” 의 div 에 내용을 추가해 준다.

TypeScript 추가

npm 명령어를 이용해서 TypeScript 를 추가해 준다. 한가지 주의해야 할 것은 결과물은 어짜피 JavaScript 로 나오기 때문에 개발할때만 TypeScript 만 필요하게 된다. 따라서 npm 을 이용해 설치할 때에는 개발목적으로 설치 하는게 좋다. ‘–save-dev’ 옵션을 사용하면 개발목적으로 설치할 수 있다.

위 명령어는 다음과 같이 축약 할 수 있다.

설치를 하고 나면 다음과 같이 package.json 파일에 TypeScript 의존성이 추가 된다.

‘devDependencies’ 는 개발목적의 의존성을 말하며 그 안에 TypeScript 가 있다. 설치된 버전은 최신버전으인데, 설치할때에 버전을 따로 지정해 주지 않으면 최신버전으로 설치가 된다.

이제 TypeScript 를 위한 설정 파일을 root 폴더에 ‘tsconfig.json’ 이름으로 생성해 준다.

몇가지 설정은 다음과 같다.

  • ‘noEmit’ 를 true 로 하게되면 TypeScript 컴파일러가 아무것도 트랜스파일(trnaspilation)을 하지 않는다.
  • ‘allowSyntheticDefaultImports’ 와 ‘esModuleInterop’ 를 true 로 하게 되면 React 를 디폴트 임포트해준다. import React from ‘react’ 를 자동으로 해주는데, false 로 되었을 경우에는 import * as React from ‘react’ 로 임포트 된다.
  • ‘forceConsistentCasingInFileNames’를 true로 설정하면 임포트문에서 참조된 파일 이름의 케이싱이 일관되게 유지되는지 확인할 수 있는 타입 체킹 프로세스가 활성화 된다.

React 추가

이제 React 와 TypeScript 를 설치 한다.

‘react’ 는 react 에 코어 라이브러리다. 모든 React 관련 라이브리가 사용한다. ‘react-dom’ 은 웹 앱(web app) 을 빌드하는데 사용되는 라이브러리다.

React 는 TypeScript 를 포함하지 않는다. 따라서 별도로 설치를 해줘야 하는데, 다음과 같이 해준다.

‘–save-dev’ 옵션을 줘서 개발목적으로만 설치를 한다. 빌드하고 나온 결과물은 Javascript 로 되기 때문에 TypeScript 는 필요가 없기 때문에 개발목적으로만 설치를 하면 된다.

src 폴더에 루트(root) 컴포넌트라고 하는 ‘index.tsx’ 파일을 작성한다.

위 코드는 id 가 ‘root’ 인 DOM 에 React 앱을 주입시켜 준다. 확장자가 js 가 아닌 tsx 로 한 이유는 Babel이 트랜스컴파일을 위해 JSX 를 포함하는 TypeScript 파일을 자동으로 찾도록 하고 TypScript 가 타입 체크 프로세스를 진행할 수 있도록 한다. 확장자가 ts 인 경우에는 TypeScript 코드인데 JSX 를 포함할 수 없다.

‘document.getElementById(‘root’) as HTMLElement’ 에서 ‘as HTMLElement’ 를 type assertion 이라고 하는데, TypeScript 를 이용하기 때문에 어떤 타입인지를 명시를 해줘야 한다. ‘document.getElementById’ 은 ‘as HTMLElement’ 거나 null 타입을 가질 수 있는데, ‘as HTMLElement’ 타입을 가지라고 명시하고 있다.

Babel 추가

Babel 은 React 와 TypeScript 코드를 JavaScript 코드로 트랜스파일(transpile, 혹은 transcompile)을 해준다. 역시 결과물은 JavaScript 만 있으면 되는거라서 개발목적으로만 설치하면 된다.

또, 최신의 JavaScript 기능을 사용하도록 하기 뒤해서 @babel/preset-env 라고 하는 Babel 플러그인을 설치해 준다.

또, React 를 JavaScript 로 변환하기 위해 @babel/preset-react 라고 하는 Babel 플러그인을 설치해 준다.

똑같이 TypeScript 를 JavaScript 로 변환하기 위해 @babel/preset-typescript 라고 하는 Babel 플러그인을 설치해 준다.

마지막으로 JavaScript 에 async 와 await 를 사용할 수 있도록 다음 두개의 플러그인을 설치해 준다.

Babel 관련해 설치는 마무리 되었다. 이제 .babelrc.json 설정 파일을 다음과 같이 작성해 준다.

위 설정은 Babel 에게 설치된 Babel 플러그인들을 사용하도록 하며 설정된 되로 동작하도록 한다.

Webpack 추가

Webpack 은 주로 JavaScript 소스 코드 파일을 함께 묶는 유명한 툴이다. 파일을 스캔하는 것처럼 Babel 과 같은 다른 툴들을 실행시킬 수 있다. 또, 모든 소스 파일을 스캔하고 이것을 JavaScript 파일로 트랜스파일해 준다. Webpack 으로 만들어지는 결과물은 index.html 파일 하나로 작성되며 JavaScript 소스코드로 이 안에 있게된다.

Webpack 설치

Webpack 설치는 다음과 같다.

Webpack 은 ‘webpack’ 패키지 안에 TypeScript 타입을 가지고 있어서 별도로 TypeScript 를 설치하지 않아도 된다.

다음으로 Webpack 개발 서버를 설치한다.

Webpack 개발 서버는 개발하는 동안 사용되는 서버로, 소스코드가 변경되면 자동으로 웹 앱을 업데이트 해준다.

Babel 이 React 와 TypeScript 코드를 JavaScript 로 트랜스파일하도록 Webpack 플러그인을 설치 해줘야 한다. 이 플러그인을 ‘babel-loader’ 라고 한다.

Webpack 은 React 앱을 호스트 하기 위해 index.html 파일을 생성할 수 있는데, 마치 템플릿 처럼 그리고 React 앱들을 index.html 파일로 번들하기 위해서 index.html 파일을 사용할 것이다. 이러한 기능을 위해서 ‘html-webpack-plugin’ 플러그인을 설치해야 한다.

이제 Webpack 과 연관된 라이브러리 설치가 모두 끝났다.

Webpack 설정

Webpack 개발을 위한 설정이 필요하다. 먼저 설정을 TypeScript 형식으로 기술할 수 있도록 ‘ts-node’ 플러그인을 설치한다.

이제 TypeScript 형식으로 Webpack 설정을 할 수 있다. Webpack 개발 설정 파일 이름은 ‘webpack.dev.config.ts’ 로 한다. ts 확정자를 가지고 있기 때문에 TypeScript 를 사용할 수 있으며, 이는 ‘ts-node’ 플러그인 때문에 가능한 것이다.

프로젝트 루트 디렉토리에 ‘webpack.dev.config.ts’ 파일을 다음과 같이 작성한다.

  • ‘import path’ 는 webpack 번들이 어디에 위치하는지 지정할 수 있다.
  • ‘import HtmlWebpackPlugin’ 은 index.html 파일 생성할 수 있도록 해준다.
  • webpack 설정 TypeScript 타입은 ‘webpack’ 과 ‘webpack-dev-server’ 패키지에서 제공된다. intersect type 을 사용해 이를 연결하고 Configuration이라는 타입을 만든다.

‘const config: Configuration’ 에서 Configuration 타입을 사용하는 것을 알 수 있다. 위 설정에 대해서 다음과 같은 의미를 가진다.

  • mode: ‘development’ 는 개발 모드를 지정한다. 이 모드는 React 개발 툴을 포함한다는 뜻이다.
  • output.publicPath 는 앱의 root 패스다.
  • entry 프로젝트에서 React 앱의 엔트리 지점인 index.tsx 가 어디에 있는지를 webpack 에게 알려준다.
  • Webpack 은 configuration 객체를 기본적으로 export 되기를 기대하기 때문에 기본적으로 export default config 를 해줘야 한다.
  • module 속성은 webpack 에게 다른 모듈을 어떻게 처리해야하는지 알려준다. webpack 에게 .js, .ts, tsx 확정자를 가지는 파일에 대해서 babel-loader 를 사용하라고 알려준다.
  • resolve.extensions 속성은 webpack 이 모듈을 해석하는 동안 TypeScript 파일과 JavaScript 파일을 찾을 수 있게 알려준다.
  • HtmlWebpackPlugin 은 HTML 파일을 생성하는데, src/index.html 을 생성하도록 한다.
  • HotModuleReplacementPlugin 는 모듈이 앱을 실행하는 동안에 전체 릴로드 없이 업데이트 하도록 해준다.
  • devtool 속성은 webpack 이 전체 인라인 소스 맵(full inline source map) 을 사용하라고 알려준다. 이는 트랜스파일하기 전에 원본 소스코드를 디버깅할 수 있도록 해준다.
  • devServer 속성은 webpack 개발 서버를 위한 설정이다. 이 설정에 따르면, 웹 서버의 포트는 4000 이며 루트 디렉토리는 dist 폴더다. historyApiFallback 는 deep link 를 위해 필요하며, open: true 는 서버가 시직되면 자동으로 브라우저를 열도록 한다.

이제 webpack 서버를 구동하기 위한 Script 를 package.json 파일에 설정해 준다.

Webpack 웹 서버 실행

이제 모든 준비는 끝이 났다. 다음과 같이 웹 서버를 실행 시켜 준다.

정상적으로 실행이 되었다면 자동으로 브라우저가 실행되면서 화면이 출력된다.

React + TypeScript 설치 방법중에 한가지로 Webpack 을 이용하는 방법에 대해서 알아봤다.

Harbor 업데이트 하기

현재 개인적으로 Harbor 를 사용하고 있다. 별로 중요하지 않은 프로젝트여서 크게 신경쓰지 않는 저장소인데, 그래도 이래저래 테스트를 하는데 유용하다. Harbor 를 사용하다가 새로운 버전이 출시되어서 어떻게 업데이트를 했는지를 기록으로 남겨둔다.

Harbor Stop

Harbor 를 정지 시켜야 한다. Harbor 는 Docker-compose 기반으로 작동됨으로 docker-compose 명령어를 이용해서 다음과 같이 정지를 시켜줘야 한다.

Backup

혹시 잘못됐을때를 대비해 Backup 을 해준다. 디렉토리를 그냥 복사해주는 것으로 하면 된다.

새로운 버전 다운로드

Docker 명령어를 이용해서 새로운 버전의 harbor 이미지를 다운로드 한다.

데이터베이스 Migration 하기

기존의 데이터베이스를 새로운 버전으로 Migration 을 해야 한다.

데이터베이스 마이그레이션할 내용이 없으면 그냥 끝나게 된다.

새로운 버전 다운로드 후 설치

새로운 버전의 Harbor 을 다운로드 하고 난후, install.sh, common.sh, prepare 파일을 기존 디렉토리에 복사해 준다.

설치

이제 새로운 버전을 설치를 한다.

크게 어려운건 없다. 순서대로 했는데 중간에 문제가 되거나 하지 않았다. 업데이트를 한 후에 저장소를 사용하고 있는데, 기존 자료가 이상해지거나 되는 기능이 되지 않는 문제는 없었다.

유용한 Git 명령어

유용한 Git 명령어 정리.

Git 설정

대부분 Git 설정은 명령어로 한다.

하지만 Git bash 를 이용할 경우에 설정 파일을 직접 편집하도록 할 수도 있다.

브랜치 리스트

로컬 브랜치 삭제

원격 브랜치 삭제

원격 브랜치 삭제는 branch 명령어를 사용하지 않는다.

로컬에 원격 브랜치 목록 업데이트

원격 브랜치 목록 보기를 했을때에 실제 원격 브랜치와 차이가 있을 수 있다. 이것때문에 헷깔릴 수 있는데, 원격 브랜치 목록을 로컬에 반영하기 위해서는 다음과 같이 해준다.

prune 을 자동으로 되도록 설정할 수 있다.

git 설정 파일에서는 다음과 같이 설정할 수 있다.

Spring boot 에 systemd 유닛 만들기

요즘 프로젝트를 하고 있는데, 역시나 자바 시스템이 있다. Spring Boot3 을 사용하고 있고 자바 17을 쓰는등 나름대로 괜찮은 환경에서 개발이 이루어지고 있다. 그런데, 이것을 서버에서 배포를 하고 Spring Boot 를 실행해야 하는데, 어떻게 하나 봤더니 초보자 수준도 못 벗어나는 설정을 하고 있으니… 안타까운 마음에 어떻게 하는 것이 좋은 것인지 한번 적어봤다.

Spring boot, jar 실행 파일

Spring Boot3 를 컴파일 하면 jar 파일 나온다. 그리고 별다른 서버 없이도 바로 실행하고 접속이 가능해 진다. 한가지 재미있는 사실은 많은 사람들이 Spring boot3 에 실행 파일 jar 이 내장된 WAS 서버가 구동되면서 실행된다는 걸 모른다는 거다. 심지여 그것이 Tomcat 이라는 것도. 물론 어떤 프로그래밍 모델인지에 따라서 Tomcat 이 되기도 하고 Netty 되기도 하지만, 과연 Reactive Programming Model 로 짜는 사람이 몇이나 있나 싶다. 대부분 Spring MVC 이고 Servlet 이면 기본적으로 Tomcat 이 구동된다. 내장형 Tomcat

프로젝트에서 쓰는 방법

현재 프로젝트에서는 jar 실행을 위해서 스크립트 파일을 만들었다. 대략 다음과 같다.

자바 옵션인 -D 옵션과 jar 실행 파일을 인자로 주고 있다. 그런데, 특이하게도 데몬화를 하지 않았고 많은 초보자식 설정인 nohup 도 없다. 이렇게되면 프로그램이 포그라운드(Foreground) 실행이되어서 쉘이 묶이게 된다.

어떻게 했지? 봤더니 systemd 에 이 실행파일을 넣고 systemd 를 통해서 시작/중지를 하고 있었다. 다음과 같다.

‘ExecStart=’ 에 쉘 스크립트 실행 파일을 지정해 주고 있다.

왜 이렇게 해야 하나? 왜? 이해 할 수 없는 구조다.

Spring 공식 문서

Systemd 유닛에 등록하는 방법은 Spring 공식문서에도 나와 있다.

57.1.2 Installation as a systemd service

이 문서에 나온 systemd 유닛 파일은 프로젝트 유닛 파일과 다르다. 공식 문서에 내용은 그냥 아주 기초적인 내용만 적혀 있다. 실제 프로젝트에 적용하기에는 무리가 있다.

설정파일 작성

Spring boot 를 위한 설정을 systemd 유닛에서 사용할 수 있는 별도의 파일로 작성한다. 이 설정은 JAVA_OPTS 의 내용을 담으면 된다.

이것을 이제 systemd 에서 사용하면 다음과 같다.

공식문서에 나와 있는 내용과 EnvironmentFile 속성으로 외부에서 JAVA_OPTS 를 지정한 내용을 읽어오도록 하면 충분히 사용가능해 진다.

프로젝트에서 처럼 스크립트로 한번 감싸고 이것을 다시 systemd 유닛에서 실행되도록 할 필요가 없다는 것이다.

몇가지 개선 설정

공식문서는 간단한 예이다. 실행이 가능한 정도의 유닛 파일일 뿐이다. systemd 를 이용해 자바 애플리케이션을 실행할 때에는 여러가지를 고려해야 한다.

일단 자바 애플리케이션은 네트워크를 기반으로 한다. 따라서 네트워크 온라인 상태여야 한다. 또, StdOut, StdErr 를 Journal 로 내보내도록 해야 한다.

CloudWatch Log 총 용량 계산하기

CloudWatch Log 의 총 용량의 사용량을 알아야 얼마 정도 비용이 나가는지를 추정할 수 있다. CloudWatch Log 화면에서 총 용량을 보여주면 고맙겠지만 그런게 없다보니 비용이 얼마정도 나가는지도 모르게된다.

Python 을 이용해서 총 용량을 계산해보자.

nextToken

AWS SDK 를 사용하는데 있어 항상 나오는 것이 nextToken 이다. AWS 는 무제한으로 API Call 을 하도록 허용하지도 않고 결과의 모두를 출력해주지 않는다. 다음을 보자.

describe_log_groups 메소드에 인자값으로 limit 가 있다. 이 값은 Default 값이 있다. 문제는 이 인자값을 50 이상을 지정할 수가 없다는 것이다. CloudWatch Log 개수가 50개 이상이라면 딱 50개 만 출력이되는데, 나머지를 출력하고 싶다면 nextToken 인자를 주면 된다.

일종의 Pagenation 개념으로 다음 페이지를 넘기며 출력을 하도록 하면 전체 CloudWatch Log 를 가지고 올 수 있다.

storedBytes

CloudWatch Log 에 SDK 에 리턴값은 Dictionary 로 나온다. 여기에는 logGroups 키로 하는 리스트형태의 Dictionary 인데, 여기에는 logGroupName, storedBytes 이며 storedBytes 값을 다 더하면 된다.

이런식으로 totalStoredBytes 에 전체용량을 저장하고 출력하면 된다.

전체소스

전체 소스는 다음과 같다.

좀 더 개선된 코드를 생각해 볼 수 있다. 그건 여러분이들 해보라.

node_exporter 설치하기

node_exporter 는 OS 에 대한 각종 지표를 수집해주는 exporter 다. Prometheus 가 읽어 갈수 있도록 작은 웹서버로 작동된다.

설치야 바이너리로 배포를 하기 때문에 아키텍쳐에 맞게 다운받아서 설치를 하면 된다. 압축 풀고 시작하면 그만일 정도로 아주 간단하다. Prometheus 에 exporter들은 대부분 간단하다. 복잡하게 설치하지는 않는다.

그런데… 고려해야하는 부분이 존재한다. 일단, 설치부터…

Download & Install

다운로드는 Github 저장소에 받으면 된다.

node_exporter 디렉토리가 보이고 그 안에 node_exporter 바이너파일이 있다. 이것을 적당한 곳으로 이동시키놓으면 끝난다.

어떻게 시작/중지 할건지…

여기서 이제 고민을 해야한다. 많은 사람들은 이것을 쉘 스크립트와 nohup 을 사용하는 사람들이 있다. 어느 시대에 살고 있는 사람들인지 의심이 될 정도인데, 이제는 init script 도 다 없어질 만큼 대부분의 배포판들이 systemd 로 다 전환이 완료된 상태다.

그러면 당연히 systemd 로 하면 되지! 하지만 여기서 문제가 된다.

현재 systemd 는 지속적으로 지금도 버전업이 되고 있다. 그러다보니 특정 버전을 기준으로 특정 기능이 지원이되고 안되고가 갈리게 된다.

systemd 버전 240 …. (대체 어떻게 버전 관리를.. 어떻게 기능을 많이 집어넣었으면 버전이 240 이여.. -_-;; ) 왠만하면 systemd 버전 240 이상을 사용할 것을 권한다. 그런데, 이게 말처럼,, 240버전을 써라~~ 한다고 되는게 아니다.

systemd 는 리눅스 시스템의 뼈대라고 보면된다. 핵심중에 핵심! 그러다보니 systemd 는 배포판과 함께 제공되고 묶여 있다. 240버전을 쓰고 싶다면 240버전을 가진 배포판을 써야 한다는 뜻이 된다.

  • Ubuntu 22.04: 249.11-0ubuntu3.12
  • RHEL 8.10: 239-82.el8_10.1

이런 저런 사유로 배포판을 선택하고 거기다 버전을 선택하게 된다. 내가 하고 있는 프로젝트에서는 CentOS, RHEL 7.9 가 대부분이고 RHEL 8 은 최신형으로 취급하는데.. systemd 만 놓고 보면 RHEL 8 도 그다지 마음에 들지 않는 부분이다.

개인적으로 RHEL 8 도 이제는 끝물이다. RHEL 9 의 버전이 이제는 벌써 9.3을 벗어나고 있기 때문에 이제는 RHEL 9 로가야 한다.

아무튼, 말이 길었는데, systemd 유닛으로 만들어 보자..

일단, node_exporter 에는 많은 옵션들이 있다. Prometheus exporter 들이 많은 옵션들을 제공한다. 이러한 옵션들은 별도의 파일로 작성하고 쉘 변수로 만들어 두고 systemd 유닛에서 읽어들이도록 하면 된다.

/etc/sysconfig/node_exporter 파일에 다음과 같이 내용을 적어준다.

/etc/sysconfig/node_exporter 는 RedHat 기반에 적합하다. Ubuntu 면 /etc/sysconfig 디렉토리가 없기 때문에 Ubuntu 레이아웃에 맞는 곳에 넣으면 된다.

systemd 유닛 파일은 별거 없다.

딱 보면 별거 없다….. 하지만,,, 240 이하에서는 출력되는 로그들… 일명 Standard Out 들을 어떻게 처리할까? 그냥 이대로 둬도 되나? 결론은 되긴 한다. 이렇게 그대로 두면 node_exporter 가 뭔가를 출력하면 stdout, stderr 로 내보낸다. 그러면 systemd 는 이것을 /var/log/syslog 파일에 기록하게 된다.

하지만, systemd 로 변경되면서 나온 journal 에 기록을 하고 싶을지도 모른다. 이왕이면 그렇게하는게 좋기도 하다. 그래서 다음과 같이 [Service] 세션에 StandardOutput 옵션을 준다.

콘솔에도 출력을…. 뭐.. 이건 옵션이다. 여기서 systemd 버전에 따라서 파일에 redirect 가 가능하기도 하고 불가능하기도 하다. StandardOutput 에 옵션이 inherit, null, tty, journal, kmsg, journal+console, kmsg+console, file:path, append:path, truncate:path 이렇게 되어 있다. 이게 다 가능한게 아니다. 버전에 따라서 가능하기도 하고 불가능하기도 하다.

Systemd 버전

새로운 배포판에 따라서 systemd 의 버전이 달라진다. 문제는 대부분 systemd 버전이 특정 시점까지만 업데이트가 된다. 시스템에 뼈대이다 보니 확 갈아 엎을 수 없는 것이여서 그럴거다.

이러다보니 특정 기능을 탐이 나는 때가 있는데, OS 를 다 갈아 엎어야하는 고충이 있다. 그래서 이왕이면 새로운 시스템을 구축할때에는 왠만하면 최신판을 쓰는게 좋다. Ubuntu 라면 24.04, RedHat 이면 9.0 을 사용하길 권한다.