Notification 알림으로 인한 Activity 중복 호출 방지

반응형

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Activity 중복 생성 방지
        if (!isTaskRoot) {
            finish()
            return
        }

}

 

반응형

댓글()

[Android Kotlin] 포그라운드 서비스 (Foreground Service)

반응형

[출처] https://iamjm29.tistory.com/13

 

자세한 설명은 출처를 확인하도록 합니다.

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
http://schemas.android.com/apk/res/android"</linearlayout xmlns:android="
    xmlns:app="
http://schemas.android.com/apk/res-auto"
    xmlns:tools="
http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <Button
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:text="Start Service"
        android:id="@+id/btn_start"/>

    <Button
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:text="Stop Service"
        android:id="@+id/btn_stop"/>

</LinearLayout>

 

 

AndroidManifest.xml

아래 전체를 복사하지 말고, 색칠한 곳만 참고하도록 합니다.

생성된 패키지명이 다르면 테마 이름도 다르기 때문입니다.

<?xml version="1.0" encoding="utf-8"?>
http://schemas.android.com/apk/res/android"</manifest xmlns:android="
    xmlns:tools="
http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Test"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true" />

    </application>

</manifest>

 

 

MainActivity.kt

package kr.sysdocu.test

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    //Button
    var btn_start: Button? = null
    var btn_stop: Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn_start = findViewById(R.id.btn_start)
        btn_stop = findViewById(R.id.btn_stop)

        btn_start!!.setOnClickListener(View.OnClickListener {
            val serviceIntent = Intent(this@MainActivity, MyService::class.java)
            startService(serviceIntent)
            Toast.makeText(this@MainActivity, "Service start", Toast.LENGTH_SHORT).show()
        })

        btn_stop!!.setOnClickListener(View.OnClickListener {
            val serviceIntent = Intent(this@MainActivity, MyService::class.java)
            stopService(serviceIntent)
            Toast.makeText(this@MainActivity, "Service stop", Toast.LENGTH_SHORT).show()
        })
    }
}

 


MyService.kt

package kr.sysdocu.test

import android.app.*
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat

class MyService : Service() {
    private var mThread: Thread? = null

    companion object {
        private const val TAG = "MyService"
        private const val NOTI_ID = 1
    }

    private fun createNotification() {
        val builder = NotificationCompat.Builder(this, "default")
        builder.setSmallIcon(R.mipmap.ic_launcher)
        builder.setContentTitle("Foreground Service")
        builder.setContentText("포그라운드 서비스")
        builder.color = Color.RED

        val notificationIntent = Intent(this, MainActivity::class.java)
        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
        val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
        builder.setContentIntent(pendingIntent) // 알림 클릭 시 이동

        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationManager.createNotificationChannel(
                NotificationChannel(
                    "default",
                    "기본 채널",
                    NotificationManager.IMPORTANCE_DEFAULT
                )
            )
        }
        val notification = builder.build()
        startForeground(NOTI_ID, notification)
    }

    override fun onCreate() {
        super.onCreate()
        createNotification()
        mThread = object : Thread("My Thread") {
            override fun run() {
                super.run()
                for (i in 0..99) {
                    Log.d(TAG, "count : $i")
                    try {
                        sleep(1000)
                    } catch (e: InterruptedException) {
                        currentThread().interrupt()
                        break
                    }
                }
            }
        }
        mThread!!.start()
        Log.d(TAG, "onCreate")
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        Log.d(TAG, "onStartCommand")
        return START_NOT_STICKY
    }

    override fun onDestroy() {
        super.onDestroy()
        if (mThread != null) {
            mThread!!.interrupt()
            mThread = null
        }
        Log.d(TAG, "onDestroy")
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
}

 

 

 

 

반응형

댓글()

AndroidStudio 에서 JAVA 로 GPS 현재 위치 확인하기

프로그래밍/Android (Java)|2024. 11. 1. 18:47
반응형

[출처] https://mainia.tistory.com/1153

출처에서 activity_main.xml 파일 내용만 추가하여 테스트하였고 정상 동작 확인하였습니다.

 

 

1. AndroidManifest.xml

...
    </uses-permission android:name="android.permission.internet" >
    </uses-permission android:name="android.permission.access_fine_location" >
    </uses-permission android:name="android.permission.access_coarse_location">
...

 

 

2. MainActivity.java

package kr.sysdocu.position;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/** GPS 샘플 */
public class MainActivity extends Activity {

    private Button btnShowLocation;
    private TextView txtLat;
    private TextView txtLon;
    private final int PERMISSIONS_ACCESS_FINE_LOCATION = 1000;
    private final int PERMISSIONS_ACCESS_COARSE_LOCATION = 1001;
    private boolean isAccessFineLocation = false;
    private boolean isAccessCoarseLocation = false;
    private boolean isPermission = false;

    // GPSTracker class
    private GpsInfo gps;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnShowLocation = (Button) findViewById(R.id.btn_start);
        txtLat = (TextView) findViewById(R.id.tv_latitude);
        txtLon = (TextView) findViewById(R.id.tv_longitude);

        // GPS 정보를 보여주기 위한 이벤트 클래스 등록
        btnShowLocation.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                // 권한 요청을 해야 함
                if (!isPermission) {
                    callPermission();
                    return;
                }

                gps = new GpsInfo(MainActivity.this);
                // GPS 사용유무 가져오기
                if (gps.isGetLocation()) {

                    double latitude = gps.getLatitude();
                    double longitude = gps.getLongitude();

                    txtLat.setText(String.valueOf(latitude));
                    txtLon.setText(String.valueOf(longitude));

                    Toast.makeText(
                            getApplicationContext(),
                            "당신의 위치 - \n위도: " + latitude + "\n경도: " + longitude,
                            Toast.LENGTH_LONG).show();
                } else {
                    // GPS 를 사용할수 없으므로
                    gps.showSettingsAlert();
                }
            }
        });

        callPermission();  // 권한 요청을 해야 함
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                           int[] grantResults) {
        if (requestCode == PERMISSIONS_ACCESS_FINE_LOCATION
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            isAccessFineLocation = true;

        } else if (requestCode == PERMISSIONS_ACCESS_COARSE_LOCATION
                && grantResults[0] == PackageManager.PERMISSION_GRANTED){

            isAccessCoarseLocation = true;
        }

        if (isAccessFineLocation && isAccessCoarseLocation) {
            isPermission = true;
        }
    }

    // 전화번호 권한 요청
    private void callPermission() {
        // Check the SDK version and whether the permission is already granted or not.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            requestPermissions(
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    PERMISSIONS_ACCESS_FINE_LOCATION);

        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED){

            requestPermissions(
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                    PERMISSIONS_ACCESS_COARSE_LOCATION);
        } else {
            isPermission = true;
        }
    }
}

 

 

3. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <!-- 시작 버튼 -->
    <Button
        android:id="@+id/btn_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="위치 가져오기" />

    <!-- 위도 표시 -->
    <TextView
        android:id="@+id/tv_latitude"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="위도: "
        android:textSize="18sp"
        android:paddingTop="20dp" />

    <!-- 경도 표시 -->
    <TextView
        android:id="@+id/tv_longitude"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="경도: "
        android:textSize="18sp"
        android:paddingTop="10dp" />

</LinearLayout>

 

 

4. GpsInfo.java

package kr.sysdocu.test;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import androidx.core.content.ContextCompat;

public class GpsInfo extends Service implements LocationListener {

    private final Context mContext;

    // 현재 GPS 사용유무
    boolean isGPSEnabled = false;

    // 네트워크 사용유무
    boolean isNetworkEnabled = false;

    // GPS 상태값
    boolean isGetLocation = false;

    Location location;
    double lat; // 위도
    double lon; // 경도

    // 최소 GPS 정보 업데이트 거리 10미터
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;

    // 최소 GPS 정보 업데이트 시간 밀리세컨이므로 1분
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;

    protected LocationManager locationManager;

    public GpsInfo(Context context) {
        this.mContext = context;
        getLocation();
    }

    @TargetApi(23)
    public Location getLocation() {
        if ( Build.VERSION.SDK_INT >= 23 &&
                ContextCompat.checkSelfPermission(
                        mContext, android.Manifest.permission.ACCESS_FINE_LOCATION )
                        != PackageManager.PERMISSION_GRANTED &&
                ContextCompat.checkSelfPermission(
                        mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION)
                        != PackageManager.PERMISSION_GRANTED) {

            return null;
        }

        try {
            locationManager = (LocationManager) mContext
                    .getSystemService(LOCATION_SERVICE);

            // GPS 정보 가져오기
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            // 현재 네트워크 상태 값 알아오기
            isNetworkEnabled = locationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGPSEnabled && !isNetworkEnabled) {
                // GPS 와 네트워크사용이 가능하지 않을때 소스 구현
            } else {
                this.isGetLocation = true;
                // 네트워크 정보로 부터 위치값 가져오기
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            // 위도 경도 저장
                            lat = location.getLatitude();
                            lon = location.getLongitude();
                        }
                    }
                }

                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                lat = location.getLatitude();
                                lon = location.getLongitude();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return location;
    }

    /**
     * GPS 종료
     * */
    public void stopUsingGPS(){
        if(locationManager != null){
            locationManager.removeUpdates(GpsInfo.this);
        }
    }

    /**
     * 위도값을 가져옵니다.
     * */
    public double getLatitude(){
        if(location != null){
            lat = location.getLatitude();
        }
        return lat;
    }

    /**
     * 경도값을 가져옵니다.
     * */
    public double getLongitude(){
        if(location != null){
            lon = location.getLongitude();
        }
        return lon;
    }

    /**
     * GPS 나 wife 정보가 켜져있는지 확인합니다.
     * */
    public boolean isGetLocation() {
        return this.isGetLocation;
    }

    /**
     * GPS 정보를 가져오지 못했을때
     * 설정값으로 갈지 물어보는 alert 창
     * */
    public void showSettingsAlert(){
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

        alertDialog.setTitle("GPS 사용유무셋팅");
        alertDialog.setMessage("GPS 셋팅이 되지 않았을수도 있습니다. \n 설정창으로 가시겠습니까?");

        // OK 를 누르게 되면 설정창으로 이동합니다.
        alertDialog.setPositiveButton("Settings",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,int which) {
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        mContext.startActivity(intent);
                    }
                });
        // Cancle 하면 종료 합니다.
        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });

        alertDialog.show();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    public void onLocationChanged(Location location) {
        // TODO Auto-generated method stub

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }
}

 

 

 

 

 

 

 

 

반응형

댓글()

ffmpeg 명령어로 포맷 변환 예제 (mkv to mp4, mp4 to mp3)

리눅스/OS 일반|2024. 11. 1. 18:47
반응형

ffmpeg 명령으로 할 수 있는것은 다양하지만, 필자의 필요에 의해서 아래 내용만 기록해 둡니다. 

 

 

1. mkv to mp4

 

# ffmpeg -i example.mkv -c:v copy -c:a copy example.mp4

 

입력 파일 : example.mkv

출력 파일 : example.mp4

 

위 옵션 사용시 비디오 및 오디오 스트림이 원본 품질로 유지됩니다.

이 방식은 매우 빠르고 효율적이며, 데이터 손실이 없습니다.

 

 

2. mp4 to mp3

 

영상에서 오디오만 추출이 가능합니다.

 

# ffmpeg -i input.mp4 -q:a 0 -map a output.mp3

 

-i input.mp4 : 입력 MP4 파일

-q:a 0 : 오디오 품질을 최상으로 설정 (-q:a 0 대신에 -b:a 128k 와 같이 비트레이트 지정 가능)

-map a : 오디오 스트림만 추출

output.mp3 : 출력 MP3 파일 이름

 

특정 시간대의 오디오만 추출하려면 -ss (시작 시간) 와 -t (지속 시간) 를 추가합니다.

 

# ffmpeg -ss 00:01:00 -i input.mp4 -to 00:00:30 -q:a 0 -map a output.mp3

 

-ss 00:01:00 : 추출 시작 시간 (1분 0초)

-t 00:00:30 : 추출 지속 시간 (0분 30초)

-q:a 0 : 오디오 품질을 최상으로 설정 (-q:a 0 대신에 -b:a 128k 와 같이 비트레이트 지정 가능)

빠른 처리를 위해 -ss 옵션을 입력 파일 앞에 배치 하였습니다.

  이 경우, ffmpeg는 해당 시간대부터 직접 처리하므로 더욱 빠릅니다.

- mp4 말고 오디오파일 mp3 에서 부분 추출도 가능합니다.

 

반응형

댓글()

VideoJS 로 웹페이지에서 동영상 플레이어 사용하기

반응형

소스코드는 굉장히 단순합니다.

아래 옵션중 vjs-big-play-centered 는 플레이 버튼을 중앙에 두며, 미설정시 좌측 상단에 버튼이 위치합니다.

스마트폰에서 재생 버튼이 느리게 동작되어 영상을 다운로드 후 재생하는 듯 보인다면 웹서버에 H.264 모듈을 설치하여 스트리밍이 가능합니다.

 

<head>
        <meta charset="UTF-8">
        <link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.10.2/video-js.min.css" rel="stylesheet" />

        <script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.10.2/video.min.js"></script>

</head>


<body>
<video id="my-video" 

class="video-js vjs-big-play-centered

controls 

preload="auto" 

width="320

height="180

data-setup='{
"autoplay": true
}'>
        <source src="The.mkv" type='video/mp4'>

        <track kind="subtitles" src="The.vtt" srclang="ko" label="Korean" default />

</video>

</body>

 

 

* 참고 (SRT -> VTT 자막 변경 명령어)

아래 3가지만 고치면 되지만, 번거로우므로 명령어를 사용합니다.

- 시간 정보에 , (콤마) 대신 . (점)

- 자막 순번 제거

- 맨 위에 WEBVTT 라고 명시

# ffmpeg -i The.srt The.vtt

반응형

댓글()

Ubuntu 24.04 GNOME 46 Orchis 테마 적용하기

리눅스/OS 일반|2024. 9. 26. 13:53
반응형

- 로컬PC 일반 계정에서 적용이 잘 되는것 확인하였습니다.

 

파일 배포 URL

https://www.pling.com/p/2176652/

plymouth-theme.zip
0.46MB
neofetch-config.zip
0.00MB
GTK-Themes.zip
2.56MB
cava-config.zip
0.00MB
conky-config.zip
0.41MB
cursors-theme.zip
4.57MB
fonts1.zip
14.32MB
fonts2.zip
12.89MB

(fonts1.zip 과 font2.zip 는 fonts.zip 을 나누어 올린것임)

gnome-extensions.zip
1.76MB
ubuntu-desktop-settings.zip
0.01MB
fishomp-config.zip
0.12MB
wallpapers.zip
0.37MB
icon-themes.zip
19.35MB

 

 

세팅 방법 동영상 강좌

https://www.youtube.com/watch?v=5nJdzjoiygc&t=3s

 

 

Documents 에 나오는 명령어 입니다.

컨테이너 XRDP 접근하여 ubuntu 계정으로 로그인하고 진행하였습니다.

 

OS 환경 업데이트

$ sudo apt update && sudo apt dist-upgrade -y

 

어플 및 의존성 패키지 설치

$ sudo apt install curl \

rsync \

git \

gdebi \

nautilus-admin \

nautilus-extension-gnome-terminal \

sassc \

gnome-tweaks \

gnome-shell-extension-manager -y

 

리소스 파일 다운로드 (12개 파일 - fonts.zip 은 한개로 침)

$ cd Downloads

$ sudo apt -y install wget

$ wget http://sysdocu.kr/orchis/filelist.txt

$ wget -i filelist.txt

$ cd ..

 

GNOME 확장 설치

$ unzip -o $HOME/Downloads/gnome-extensions.zip -d $HOME/.local/share/gnome-shell/

 

GTK 테마 설치

$ mkdir -p $HOME/.themes
$ unzip -o $HOME/Downloads/GTK-Themes.zip -d $HOME/.themes

$ mkdir -p $HOME/.config/gtk-4.0
$ ln -sf $HOME/.themes/Orchis-Dark/gtk-4.0/{assets,gtk.css,gtk-dark.css} $HOME/.config/gtk-4.0/

 

아이콘, 커서 테마 설치

$ mkdir -p $HOME/.local/share/icons
$ unzip -o $HOME/Downloads/icon-themes.zip -d $HOME/.local/share/icons

$ mkdir -p $HOME/.icons
$ unzip -o $HOME/Downloads/cursors-theme.zip -d $HOME/.icons

 

폰트, 바탕화면 설치

$ unzip -o $HOME/Downloads/fonts.zip -d $HOME/.local/share/

$ sudo unzip -o $HOME/Downloads/wallpapers.zip -d /usr/share/backgrounds/

 

Conky 위젯 설치 및 설정

$ sudo apt install conky-all jq curl playerctl -y
$ unzip -o $HOME/Downloads/conky-config.zip -d $HOME/.config

Cava, 터미널, 오디오, 가상화, NeoFetch 설치

$ sudo apt install cava -y

$ unzip -o $HOME/Downloads/cava-config.zip -d $HOME/.config

$ sudo apt install neofetch -y

$ unzip -o $HOME/Downloads/neofetch-config.zip -d $HOME/.config

 

Fish 쉘, Oh My Posh 설치

$ sudo apt install fish -y

$ chsh -s /usr/bin/fish
Password: (ubuntu 계정 패스워드 입력)

$ sudo wget https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/posh-linux-amd64 -O /usr/local/bin/oh-my-posh

$ sudo chmod +x /usr/local/bin/oh-my-posh 
$ unzip -o $HOME/Downloads/fishomp-config.zip -d $HOME
$ chmod u+rw ~/.poshthemes/*.json

 

Flatpak, Appimage 지원 활성화

$ sudo apt install gnome-software gnome-software-plugin-flatpak flatpak libfuse2 -y

$ flatpak remote-add --if-not-exists flathub http://flathub.org/repo/flathub.flatpakrepo

(화면 팝업으로 패스워드 입력)

$ sudo flatpak install flathub io.bassi.Amberol -y    // 여기에서 원래는 sudo 가 없지만, LXC 에서는 권한이 없어 추가해보았음

 

(위가 잘 안되면 반복 하거나 메모리 증설해볼 것. 나는 어떻게 넘어감...)

 

$ sudo flatpak override --filesystem=$HOME/.themes
$ sudo flatpak override --filesystem=$HOME/.local/share/icons
$ sudo flatpak override --filesystem=xdg-config/gtk-4.0

 

GNOME 앱 설치

$ sudo apt install gnome-weather \

gnome-maps \

gnome-audio \

gnome-calendar \

gnome-clocks \

gnome-connections \

gnome-console \

gnome-contacts \

gnome-music \

vlc \

gnome-shell-pomodoro -y

 

Plymouth 테마 설치 및 변경

$ sudo apt install plymouth -y
$ sudo unzip -o $HOME/Downloads/plymouth-theme.zip -d /usr/share/plymouth/themes
$ sudo update-alternatives --install /usr/share/plymouth/themes/default.plymouth default.plymouth /usr/share/plymouth/themes/hexagon_dots/hexagon_dots.plymouth 100

$ sudo update-alternatives --config default.plymouth

(여기에서  /usr/share/plymouth/themes/hexagon_dots/hexagon_dots.plymouth   100       manual mode 행으로 된것을 찾아 앞 번호를 입력하면 됨)
$ sudo update-initramfs -u    // LXC 에서 명령어가 없다면 명령어부터 설치 sudo apt install initramfs-tools

 

GNOME 쉘 세팅 적용

$ unzip -o $HOME/Downloads/ubuntu-desktop-settings.zip -d $HOME/Downloads/
$ dconf load / < $HOME/Downloads/ubuntu-desktop-settings.conf

 

데스크톱이라면  이때 배경이 바뀌는게 보임.

LXC 는 ubuntu 계정으로 다시 로그인해야 보일지도? 메뉴를 눌러 로그아웃을 못하는 경우 호스트에서 컨테이너를 stop, start 해보자. 잘 안되네... 배경은 적용된 것 같기도 하고.. 근데 날씨 API 를 등록해야 하니, 이런건 컨테이너에서 사용 못하겠다.

 

SNAP 앱과 서비스 삭제

$ cp -afv $HOME/snap $HOME/Downloads/
$ sudo snap remove --purge firefox
$ sudo snap remove --purge snap-store
$ sudo snap remove --purge gnome-42-2204
$ sudo snap remove --purge gtk-common-themes
$ sudo snap remove --purge snapd-desktop-integration
$ sudo snap remove --purge firmware-updater
$ sudo snap remove --purge core22
$ sudo snap remove --purge bare
$ sudo snap remove --purge snapd
$ sudo apt autoremove --remove snapd -y

$ sudo rm -rf /var/cache/snapd/

$ echo "Package: snapd
Pin: release a=*
Pin-Priority: -10" | sudo tee /etc/apt/preferences.d/nosnap.pref

$ sudo apt update

 

파이어폭스 웹브라우저 설치

$ sudo add-apt-repository -y ppa:mozillateam/ppa && sudo apt update

$ echo 'APT::Key::Assert-Pubkey-Algo "";' | sudo tee /etc/apt/apt.conf.d/99weakkey-warning

$ sudo apt update

$ sudo apt install -y -t 'o=LP-PPA-mozillateam' firefox

$ echo "Unattended-Upgrade::Allowed-Origins:: \"LP-PPA-mozillateam:$distro_codename\";" | sudo tee /etc/apt/apt.conf.d/51unattended-upgrades-firefox

$ echo 'Package: firefox*
Pin: release o=LP-PPA-mozillateam
Pin-Priority: 501' | sudo tee /etc/apt/preferences.d/mozillateamppa

$ sudo apt update

 

파이어폭스 테마 설치

$ cd $HOME/Downloads

$ git clone https://github.com/vinceliuice/WhiteSur-firefox-theme.git

$ cd WhiteSur-firefox-theme/

$ sudo ./install.sh -m    // 데스크톱은 모르겠는데 LXC 에서는 sudo 를 붙여주어야 했음. 매뉴얼에서는 안붙임.

 

끝.

 

바탕화면 날씨정보 지역 ID 및 API 발급 (로그인 필요)

$ vi ~/.config/conky/Alfirk-MOD/scripts/weather-v2.0.sh

수정 후 스크립트 실행하면 적용됨

https://openweathermap.org

 

 

반응형

댓글()

Ubuntu 24.04 Desktop 에서 Samsung SL-J3560FW 프린터 잡기

리눅스/OS 일반|2024. 9. 25. 09:31
반응형

프린터 설정에서 프린터를 추가할때 Samsung SL-J3560FW 모델과 동일한 드라이버가 출력되지 않고, 삼성 홈페이지에서 조차 리눅스용 드라이버를 제공하지 않습니다.

이러한 환경에서 아래 드라이버를 선택하여 설치하였더니 잘 되는 것으로 확인 했습니다.

 

- 설정 > 프린터 > [프린터 추가] > 하단 검색창에 프린터 IP 입력

 

조금 기다리면 아래 세가지 항목이 선택항목으로 출력됩니다.

-  JetDirect

- LPD

- SL-J3560FW

 

여기에서 올바른 모델명을 선택하여 진행하면 인쇄시 글씨가 깨져 출력되므로,

JetDirect 를 선택, [추가] 하고 아래 모델명을 찾아 설치합니다.

- 제조사 : Hewlett-Packard

- 드라이버 : HP Business Inkjet 110, hpcups 3.23.12

 

반응형

댓글()

간단한 리눅스 백업 스크립트 적용하기

리눅스/OS 일반|2024. 9. 19. 08:58
반응형

백업본을 저장할 디렉토리를 생성합니다.

# mkdir /backup

 

백업 스크립트를 생성합니다.

필요에 따라 아래 내용을 수정하여 사용하면 됩니다.

# vi /root/backup.sh

#!/bin/bash

# 오래된 파일 및 디렉토리 삭제
find "/backup/" -type f -mtime +5 -exec rm -f {} \;
find "/backup/" -type d -mtime +5 -exec rm -rf {} \;

# 오늘자 백업 디렉토리 생성
today=$(date +%Y%m%d)
mkdir -p /backup/${today}

# 홈페이지 소스 및 DB 백업
cd /home/sysdocu/
tar cvzf /backup/${today}/public_html.tar.gz public_html
mysqldump -uroot -p12345678 --all-databases > /backup/${today}/all.sql

# 시스템 기본 설정 파일 백업
cd /backup/${today}
cp -arp /etc/iptables/rules.v4 .
cp -arp /etc/crontab .
cp -arp /root/backup.sh .

 

# chmod 700 /root/backup.sh

 

백업 스크립트를 매일 04시에 실행되도록 스케쥴러에 등록합니다.

# echo "0 4 * * * root sh /root/backup.sh" >> /etc/crontab

 

반응형

댓글()

Ubuntu 24.04 vsftpd 설치 및 기본 설정

리눅스/FTP|2024. 9. 13. 14:44
반응형

설치는 아래와 같습니다.
# apt -y install vsftpd

시스템 계정으로 로그인하여 파일 업로드를 사용하기 위해서는 아래 옵션으로 바꿔주어야 합니다.
# vi /etc/vsftpd.conf

# 익명 접근 차단
anonymous_enable=NO

# 로컬 사용자 계정에 대한 FTP 접속 및 쓰기 허용
local_enable=YES
write_enable=YES

# 사용자 홈 디렉토리 상위 디렉토리 이동 차단
chroot_local_user=YES
allow_writeable_chroot=YES

# 패시브 모드 설정 : 지정한 포트 범위로 데이터 전송 (방화벽에 포트 추가 필요)
pasv_enable=YES
pasv_min_port=50001
pasv_max_port=50005


수정 내용은 데몬을 재시작하여 적용합니다.
# systemctl restart vsftpd

반응형

댓글()

Ubuntu 24.04 에서 APM 설치 및 Let's Encrypt SSL 적용하기 (사이트 기본 구성)

리눅스/APACHE|2024. 9. 13. 11:54
반응형

가장 기본적인 APT 패키지 관리툴로 설치를 진행합니다.

 

 

1. APM 설치

 

# apt-get -y update

# apt-get -y upgrade

# apt-get -y install apache2

# apt-get -y install php8.3 php8.3-mysql

# apt-get -y install mysql-server

# vi /etc/apache2/mods-available/mime.conf

# 아래 내용 추가
AddType application/x-httpd-php .php .htm .html
AddType application/x-httpd-php-source .phps 

 

# vi /etc/php/8.3/apache2/php.ini

; 수정 및 추가
short_open_tag = On
extension=mysqli
extension=pdo_mysql

 

SSL 모듈을 활성화 하고 데몬을 재시작합니다.

# a2enmod ssl

# systemctl restart apache2

 


2. Virtualhost 설정

 

# cd /etc/apache2/sites-enabled

# ln -s ../sites-available/default-ssl.conf .

# vi default-ssl.conf

# 추가
ServerName sysdocu.kr
ServerAlias www.sysdocu.kr

 

# vi /etc/apache2/apache2.conf

# /var/www 디렉토리 설정을 찾아서 아래와 같이 수정, 디렉토리가 다를때는 추가
<Directory "/var/www/*">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

# 404 에러 출력시 웹서버 버전 정보 숨기기
ServerSignature Off
ServerTokens Prod

 

# systemctl restart apache2

 

 

3. Let's Encrypt SSL 설정

 

# apt -y install letsencrypt

# letsencrypt certonly -a webroot --agree-tos -m admin@sysdocu.kr -w /var/www/html -d www.sysdocu.kr --rsa-key-size 4096

 

자동 갱신 설정을 합니다.

# vi /root/ssl-renew.sh

#!/bin/bash
/usr/bin/letsencrypt certonly -a webroot --agree-tos --renew-by-default -w /var/www/html -d www.sysdocu.kr
systemctl restart apache2

 

# chmod 700 /root/ssl-renew.sh

# echo "0 0 1,16 */2 * root sh /root/ssl-renew.sh" >> /etc/crontab

 

 

4. SSL 설정

 

# vi default-ssl.conf

# 수정
SSLCertificateFile            /etc/letsencrypt/live/www.sysdocu.kr/cert.pem
SSLCertificateKeyFile    /etc/letsencrypt/live/www.sysdocu.kr/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.sysdocu.kr/fullchain.pem 

 

# systemctl restart apache2

 

 

5. SSL Redirect 설정

 

SSL 설정을 했으니, 누군가 80 포트로 접근할 경우 자동으로 443 연결을 시켜주도록 합니다.

# a2enmod rewrite

# systemctl restart apache2

# cd /var/www/html

# vi .htaccess

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.sysdocu.kr/$1 [R,L]

 

 

6. MySQL 설정

 

MySQL root 패스워드 설정 및 사용자 추가 방법입니다.

 

# mysql -p

(처음에는 패스워드가 없습니다. 그냥 엔터)

 

mysql> use mysql;

mysql> alter user root@localhost identified by '12345678';

mysql> flush privileges; 

 

새 데이터베이스와 계정 생성 후 권한을 부여 합니다.

mysql> create database sysdb;

mysql> create user 'sysuser'@'localhost' identified by '12345678';
mysql> grant all privileges on sysdb.* to 'sysuser'@'localhost';
mysql> flush privileges;

 

테스트를 위해 웹소스 루트 디렉토리 (/var/www/html) 에서 MySQL 계정을 이용한 접속 테스트 PHP 소스 코드를 작성합니다.

# vi test.php

<?
define("DB_HOST", "localhost");
define("DB_USER", "sysuser");
define("DB_PASSWORD", "12345678");
define("DB_NAME", "sysdb");
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}

$query = "SELECT VERSION()";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_array($result);
echo "version: " . $row[0];

mysqli_close($conn);
?>

 

웹브라우저를 통해 작성한 PHP 파일에 접근하면 MySQL 과 잘 연동되고 계정이 올바를 경우 아래와 같은 메세지가 출력됩니다.

여기에서는 간단히 curl 을 이용해 테스트 해보겠습니다.

# curl https://www.sysdocu.kr/test.php

version: 8.0.39-0ubuntu0.24.04.2

 

반응형

댓글()

Ubuntu 24.04 에 Prometheus + Grafana 설치하기 (GPU 포함)

리눅스/OS 일반|2024. 9. 5. 11:43
반응형

Prometheus 는 시스템 모니터링 도구로, 서버나 애플리케이션의 성능 데이터를 수집하고 경고를 설정해 문제 발생 시 알림을 주는 역할을 합니다.
Grafana 는 Prometheus 가 수집한 데이터를 시각화해 대시보드로 보여주는 도구로, 다양한 차트와 그래프로 데이터를 쉽게 분석할 수 있게 도와줍니다.
두 도구는 주로 함께 사용되어 실시간 모니터링과 시각화를 제공합니다.

Ubuntu 24.04 서버에 두개의 도구를 설치하고 사용하는 방법에 대해 설명합니다.

 

 

1. 프로메테우스 설치 및 설정

 

프로메테우스 사용자 계정을 생성합니다.

# useradd --no-create-home --shell /bin/false prometheus

 

구성 파일과 라이브러리를 저장할 디렉토리를 생성합니다.

# mkdir /etc/prometheus

# mkdir /var/lib/prometheus

# chown prometheus:prometheus /var/lib/prometheus

 

프로메테우스 바이너리 파일을 다운로드 합니다.

# wget https://github.com/prometheus/prometheus/releases/download/v2.54.1/prometheus-2.54.1.linux-amd64.tar.gz

# tar xvzf prometheus-2.54.1.linux-amd64.tar.gz

# cd prometheus-2.54.1.linux-amd64

# mv console* /etc/prometheus

# mv prometheus.yml /etc/prometheus

# chown -R prometheus:prometheus /etc/prometheus

# mv prometheus /usr/local/bin/

# chown prometheus:prometheus /usr/local/bin/prometheus

 

프로메테우스 시스템 파일을 생성합니다.

# vi /etc/systemd/system/prometheus.service

[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
    --config.file /etc/prometheus/prometheus.yml \
    --storage.tsdb.path /var/lib/prometheus/ \
    --web.console.templates=/etc/prometheus/consoles \
    --web.console.libraries=/etc/prometheus/console_libraries

[Install]
WantedBy=multi-user.target

 

변경 사항을 적용합니다.

# systemctl daemon-reload

 

프로메테우스 부팅 가동 설정과 데몬을 실행합니다.

# systemctl enable --now prometheus

 

다음 주소와 같이 웹브라우저에서 접속이 되는지 확인합니다.

http://grafana.sysdocu.kr:9090

 

 

2. Node Exporter 설치

 

# wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz

# tar xvzf node_exporter-1.8.2.linux-amd64.tar.gz

# mv node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/

 

Node Exporter 계정을 생성합니다.

# useradd -rs /bin/false node_exporter

 

Node Exporter 시스템 파일을 생성합니다.

# vi /etc/systemd/system/node_exporter.service

[Unit]
Description=Node Exporter
After=network.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter

[Install]
WantedBy=multi-user.target

 

변경 사항을 적용합니다.

# systemctl daemon-reload

 

Node Exporter 부팅 가동 설정과 데몬을 실행합니다.

# systemctl enable --now node_exporter

 

 

3. 프로메테우스 설정

 

프로메테우스에 Node Exporter 설정을 합니다.

# vi /etc/prometheus/prometheus.yml

...

scrape_configs:
  - job_name: "node_exporter"
    static_configs:
      - targets: ["localhost:9100"]
    basic_auth:
      username: 'promadmin'
      password: '12345678'

 

데몬을 재시작하여 설정을 적용합니다.

# systemctl restart prometheus

 

 

4. Grafana 설치

 

다음 명령어로 Grafana GPG 키를 추가합니다.

# wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -

 

그라파나 저장소를 추가하고 설치를 진행합니다.

# add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"

# apt -y update

# apt -y install grafana

 

부팅 실행 설정과 동시에 가동해줍니다.

# systemctl enable --now grafana-server

 

이제 웹브라우저에서 그라파나 대시보드에 접속할 수 있습니다.

주소는 아래와 같고, 기본 관리자 계정은 admin / admin 입니다.

로그인시 비밀번호 변경을 권장하고 있으므로, 바로 변경하여 보안을 강화하세요.

http://grafana.sysdocu.kr:3000

 

 

5. 프로메테우스와 그라파나 연결

 

다음은 프로메테우스 데이터 소스를 가져와 대시보드로 출력하는 과정입니다.

그라파나 대시보드에 로그인하여 아래 메뉴를 따라 이동합니다.

- Home > Connections > Data sources

열린 페이지에서 계속 진행

[ Add data source ] 클릭 > [ Prometheus ] 클릭

- Prometheus server URL : http://grafana.sysdocu.kr:9090

- Authentication methods : Basic authentication (선택), User, Password 입력 (prometheus.yml 에서 입력한 promadmin / 12345678)

- TLS settings : Skip TLS certificate validation (체크)

 

페이지 맨 하단의 [Save & test] 버튼을 눌러 이상이 없어야 합니다.

 

아래 메뉴를 따라 이동하여 대시보드 모니터링 스타일을 설정합니다.

- Dashboard > 열린 페이지에서 우측 상단 [New] 를 누르면 Import 가 보입니다. 이를 클릭합니다.

가운데 Grafana.com 의 대시보드 ID 를 넣을 수 있습니다. '15172' 를 입력하고 로드 합니다.

맨 아래 메뉴 'Select a Prometheus data source' 에서 'Prometheus' 선택 후 [Import] 를 누릅니다.

 

마지막으로, 아래 메뉴를 따라 선택하면 선택한 스타일의 대시보드에 데이터 소스값이 출력됩니다.

- Dashboards > (리스트에서) Node Exporter for Prometheus Dashboard based on 11074 > 'Resource Details: [grafana.sysdocu.kr]' 을 눌러 아래로 펼칩니다.

 

* 대시보드 레이아웃 제공 : https://grafana.com/grafana/dashboards/

 

 

※ GPU 서버 메트릭 수집

[참고] https://medium.com/@smda1215/nvidia-gpu-metrics-performance-monitor-in-grafana-prometheus-3a4bc7198cf9

 

NVIDIA GPU 서버를 모니터링 할 경우 아래와 같이 셋팅 합니다.

 

1) NVIDIA 드라이버 및 CUDA 설치

 

현재 시스템에서 사용 가능한 NVIDIA 드라이버 버전을 확인합니다.

# apt -y update

# apt -y install ubuntu-drivers-common alsa-utils

# ubuntu-drivers devices
udevadm hwdb is deprecated. Use systemd-hwdb instead.
udevadm hwdb is deprecated. Use systemd-hwdb instead.
udevadm hwdb is deprecated. Use systemd-hwdb instead.
udevadm hwdb is deprecated. Use systemd-hwdb instead.
udevadm hwdb is deprecated. Use systemd-hwdb instead.
udevadm hwdb is deprecated. Use systemd-hwdb instead.
udevadm hwdb is deprecated. Use systemd-hwdb instead.
udevadm hwdb is deprecated. Use systemd-hwdb instead.
== /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0 ==
modalias : pci:v000010DEd00001E82sv000010DEsd000012B0bc03sc00i00
vendor   : NVIDIA Corporation
model    : TU104 [GeForce RTX 2080]
driver   : nvidia-driver-470 - distro non-free
driver   : nvidia-driver-550 - distro non-free recommended
driver   : nvidia-driver-535 - distro non-free
driver   : nvidia-driver-470-server - distro non-free
driver   : nvidia-driver-535-open - distro non-free
driver   : nvidia-driver-535-server - distro non-free
driver   : nvidia-driver-535-server-open - distro non-free
driver   : nvidia-driver-550-open - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin

 

여기에서는 출력된 목록에서 추천 표시된 버전으로 설치해 보겠습니다.

# apt -y install nvidia-driver-550

 

설치가 되었으면 리부팅을 합니다.

# reboot

 

설치를 확인합니다.

(우측 상단 CUDA 버전 확인 필요)

# nvidia-smi

 

이어서 CUDA 를 설치합니다.

아래 URL 에서 미리 체크한 CUDA 버전을 선택하면 설치 방법이 안내 됩니다.

참고로, 마지막 선택 (Install Type) 에서 runfile 을 선택하면 설치가 간단해 집니다.

https://developer.nvidia.com/cuda-toolkit-archive

 

설치 방법을 따라 설치를 하면 됩니다. (Install Type 을 runfile 로 선택하면 설치가 간단해 집니다)

Ubuntu 24.04 버전은 최근에 출시되어 그런지 버전이 나와있지않아 22.04 버전으로 선택하여 설치하였습니다.

# wget https://developer.download.nvidia.com/compute/cuda/12.4.1/local_installers/cuda_12.4.1_550.54.15_linux.run

# sh cuda_12.4.1_550.54.15_linux.run

 

처음 설치 화면이 뜨기까지 시간이 걸릴 수 있으며, 설치 과정은 Continue 선택 > accept 입력 > (미리 설치했으므로) 'Driver' 제외 및 나머지 기본값으로 Install 입니다.

파일 사이즈가 크기 때문에 여기에서도 시간이 다소 소요됩니다.

 

CUDA 설치가 완료되면, ~/.bashrc 파일에 경로를 추가하여 CUDA 바이너리에 접근할 수 있도록 합니다.

# echo 'export PATH=/usr/local/cuda-12.4/bin:$PATH' >> ~/.bashrc

# echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc

# source ~/.bashrc

 

설치된 CUDA 버전을 확인합니다.

# nvcc -V

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2024 NVIDIA Corporation
Built on Thu_Mar_28_02:18:24_PDT_2024
Cuda compilation tools, release 12.4, V12.4.131
Build cuda_12.4.r12.4/compiler.34097967_0

 

2) NVIDIA GPU Exporter 설치

 

# wget https://github.com/utkuozdemir/nvidia_gpu_exporter/releases/download/v1.2.1/nvidia-gpu-exporter_1.2.1_linux_amd64.deb

# dpkg -i nvidia-gpu-exporter_1.2.1_linux_amd64.deb

 

OS 가 다른 경우, 또는 다른 버전의 패키지를 설치할 경우 배포 사이트를 방문해 보세요.

https://github.com/utkuozdemir/nvidia_gpu_exporter/releases

 

설치된 명령어가 확인됩니다.

# ll /usr/bin/nvidia_gpu_exporter 
-rwxr-xr-x 1 root root 10367128 Jun 28 21:45 /usr/bin/nvidia_gpu_exporter*

 

서비스 파일을 아래와 같이 생성합니다.

NVIDIA GPU Exporter 서비스의 기본 포트는 9835 입니다.

# vi /etc/systemd/system/nvidia_gpu_exporter.service

[Unit]
Description=Nvidia GPU Exporter
After=network-online.target

[Service]
Type=simple

User=nvidia_gpu_exporter
Group=nvidia_gpu_exporter

ExecStart=/usr/bin/nvidia_gpu_exporter

SyslogIdentifier=nvidia_gpu_exporter

Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target

 

변경 사항을 적용, 부팅 가동 설정 및 데몬 시작을 합니다.

# systemctl daemon-reload

# systemctl enable --now nvidia_gpu_exporter.service

 

웹브라우저를 통해 서비스가 잘 동작하는지 확인합니다.

http://grafana.sysdocu.kr:9835/metrics

 

3) 프로메테우스 설정

 

Nvidia GPU 매트릭을 출력할 준비가 되었습니다.

그라파나 대시보드에서 메트릭을 수집할 수 있도록 프로메테우스 설정을 변경 합니다.

# vi /etc/prometheus/prometheus.yml

...

scrape_configs:
  - job_name: 'node_exporter'
    static_configs:
      - targets: ['localhost:9835']
    basic_auth:
      username: 'promadmin'
      password: '12345678'

 

변경된 설정을 적용하기 위해 데몬을 재시작 합니다.

# systemctl restart prometheus

 

4) 그라파나 대시보드 설정

 

그라파나에서 소스데이터와 대시보드를 추가합니다.

그라파나 대시보드에 로그인하여 아래 메뉴를 따라 이동합니다.

- Home > Connections > Data sources

열린 페이지에서 계속 진행

[ Add data source ] 클릭 > [ Prometheus ] 클릭

- Prometheus server URL : http://grafana.sysdocu.kr:9090

- Authentication methods : Basic authentication (선택), User, Password 입력 (prometheus.yml 에서 입력한 promadmin / 12345678)

- TLS settings : Skip TLS certificate validation (체크)

 

페이지 맨 하단의 [Save & test] 버튼을 눌러 이상이 없어야 합니다.

 

아래 메뉴를 따라 이동하여 대시보드 모니터링 스타일을 설정합니다.

- Dashboard > 열린 페이지에서 우측 상단 [New] 를 누르면 Import 가 보입니다. 이를 클릭합니다.

가운데 Grafana.com 의 대시보드 ID 를 넣을 수 있습니다. '14574' 를 입력하고 로드 합니다.

맨 아래 메뉴 'Select a Prometheus data source' 에서 'Prometheus' 선택 후 [Import] 를 누릅니다.

 

마지막으로, 아래 메뉴를 따라 선택하면 선택한 스타일의 대시보드에 데이터 소스값이 출력됩니다.

- Dashboards > (리스트에서) Nvidia GPU Metrics 를 누르면 대시보드가 출력됩니다.

 

* NVIDIA 를 기준으로 하였지만, Tesla 도 되는듯 합니다.

 

반응형

댓글()