• 파이썬 서버 체크 requests try catch timeout

    파이썬 서버 체크 requests try catch timeout

    파이썬 서버 체크

    파이썬을 이용하여 운영중인 웹서버 도메인을 쉽게 확인 할 수 있습니다.

    timeout = 3 초 되어있는데 자신의 서버에 맞게 세팅하세요.

    5초~10초 정도 해도 적당합니다.

    타임아웃으로 나오는 경우는 단순 서버가 느리게 반응하는것입니다.

    그러니 여유있게 잡아주시고요.

    BAD 나올 경우랑 Connection Error 나올 경우에는 필히 서버를 체크해주세요

    _______def_url_list 파일에는 url_list 배열이 들어 있습니다.

    파이썬 서버 체크 결과화면

    웹서버가 많을 수록 이 소스는 자주 사용됩니다.

    잘 사용하세요.

    나중에 문제 있는 서버가 있으면 SMS로 알려주는 기능 추가해봐야겠네요.

    돌아다니면서 문자 오면 서버 이상 증상 바로 확인 되도록요.

    혹시 기능 필요하신 분들 계시면 연락주세요.

    연락은 스마트폰에서 접속해서 아래를 클릭하면 문자보낼수 있습니다.

    필요하신분들 클릭!!

    끝!~

  • .htaccess Redirect RewriteEngine 리다이렉트

    .htaccess Redirect RewriteEngine 리다이렉트

    이 문서는 매우 중요한 문서이며 공개 될 경우 개발자들 사이에서 많이 사용하게 됩니다.

    오늘 이 정보는 너무 중요해서 가리겠습니다.

    부자들은 아래 코드를 사용해야합니다

    [coupang]

    .htaccess Redirect

    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(domain\.com|www\.domain\.kr)
    RewriteRule (.*) https://RedirectDomain.com [L]
    
    #예시
    RewriteRule (.*) https://vlog.tion.co.kr/smartphone/?referer=refererUrl&r=refereValue [L]

    도메인을 이용하여 전체 URL에 대해서 특정 URL로 강제 리다이렉트 시킬 수 있습니다.

    이때 주의 할 점은 301 Redirect 를 사용하면 안됩니다.

    [coupang_end]

    301을 사용하게 될 경우 크롬브라우저에서 처음을 인지하지 않고 마지막을 기억하여 캐시로 바로 마지막 주소에 도달하게 됩니다. 결국 앞에 레퍼값이 모두 사라지게 되므로 원하는 그림을 만들기가 어렵게 됩니다.

    307 또는 308 리다이렉트를 사용해야하며 딜레이는 딱히 주지 않아도 됩니다.

    0초를 주던 1초를 주던 상대 도착지점에서는 레퍼값이 이전 값을 알수 없게됩니다.

    같은 정보라도 보는 사람에 따라 어떻게 활용하냐에 달려있는 거 같습니다.

    보물 지도를 보고도 그게 보물인지 모르죠.

    마치 지금 이 글처럼요..

    실제 어떻게 활용되고 응용되는지 눈응로 보여주면 ‘아~~~’ 하겠지만…

    그전까지는 그저 .haccess 301 Redirect 스크립트에 불과하죠.

    끝!

  • MYSQL DB 데이터베이스 용량 줄이기

    MYSQL DB 데이터베이스 용량 줄이기

    매월 늘어나는 빅데이터로 인해서 MySQL DB 용량은 점점 늘어나고 있습니다.

    7년전에 이미 예상했던 부분이기에 크게 놀랍지는 않습니다.

    그 당시 월단위로 20GB씩 늘어났었으며 1년에 240GB를 사용할 경우 10년에 2400GB를 확보하면 된다는 마인드로 2TB SSD를 구입하여 사용해왔습니다.

    2TB SSD를 이용할 경우 대략 10년 정도 버틸 수 있다 생각했었죠.

    실제로 용량은 그보다 더 많이 늘어났습니다.

    이미 쌓인 DB를 바탕으로 더 많은 수집 정보로 인해서 용량은 거대해지게 되었죠.

    안되겠다 싶어서 MySQL OPTIMIZE 등등 다 해보았지만 근본적으로 물리용량까지 줄일 수는 없었습니다.

    지금은 아래 테이블을 보시다싶이 1개월 단위로 용량이 눈에 띄일 정도로 많이 줄어든 상태입니다.

    제가 사용한 방법은 INDEX를 없애버린겁니다.

    인덱스가 사라지니깐 속도는 느리지만 더 많은 용량을 확보하여 하드웨어 비용적인 부분에서 절약이 많이 되었습니다.

    20GB -> 2GB로 확 줄어버리니 10년의 기간이 100년으로 늘어나게 된거죠.

    대신 어떤 데이터를 찾을 때 매우 느리다는것만 감안한다면 뭐 그리 큰 문제는 아니였습니다.

    용량을 줄여놓고보니 이번에는 가상화 VM 구조로 운영을 할 수 있게 되었습니다.

    그래서 200GB정도면 10년치를 확보 할 수 있겠다 싶어 잘 운영하고 있었죠.

    그런데 이미 7년이 넘어가는 시점에 도달하였고 역시 200GB 용량으로는 한계점이 오게되어 물리적인 용량을 늘려야 하는 시기가 또 다다르게 된것입니다.

    이번에는 조금 다른 생각을 하게되었습니다.

    기존에는 INDEX 컬럼을 삭제했다면 이번에는 물리적으로 ROW를 줄여보자는 마음이 생기더군요.

    처음부터 약속을 하는거죠.

    기준치에 미치지 못하는 경우에 대해서는 그냥 일괄 수집을 하지 않는 방법입니다.

    이 알고리즘은 아니 알고리즘이라고 말하기도 힘들죠. 그냥 방법론인거죠.

    처음에 몇가지 상태를 지정해놓고 그 상태를 바탕으로 기준에 미치지 못하면 ROW를 넣지 않고 기준에 부합할 경우에만 INSERT 시키는 방법입니다.

    이렇게 할 경우 제가 기준을 얼마나 높이냐에 따라 수집되는 데이터는 줄어들게되죠.

    대신 정확도는 점점 떨어지게됩니다.

    높은 수치를 지정해놓게되면 그 이하 수치는 모두 수집을 하지 않게 되니 정확도가 그만큼 떨어지게되죠.

    하지만 정확도와 무관하게 숫자가 0부터 1만까지가 있을 경우 0과 1은 큰차이가 생기지 않기에 0과 1을 제거 할 경우

    ROW갯수는 엄청나게 차이가 나게됩니다.

    크기 2.3GB 용량의 테이블 크기가 463.3MB 만큼 확보를 할 수 있게 되었습니다.

    바로 1에 대한 부분을 0과 퉁 쳐버린거죠.

    이제부터 0과 1은 같다 생각하고 1로 수집하는 모든 경우의 수를 배제해버리게 되죠.

    1개월에 0.5GB 정도의 용량을 확보 할 수 있다면 1년에 5기가를 확보하게 되는것입니다.

    10년이면 50기가가 되는거죠.

    MYSQL 테이블 데이터베이스 용량 줄이기

    1. 필요없는 INDEX를 삭제한다.

    인덱스 삭제는 신중해야합니다. DB속도를 좌지우지 하기 때문이죠.

    속도에 큰 문제가 없다 생각되면 삭제 하셔도 됩니다. 이때에는 ROW갯수가 100만개가 안 넘을 때 가능하죠.

    ROW갯수가 100만개가 넘어간다면 INDEX 설정은 어찌보면 필수일수 있습니다.

    테이블 갯수를 더 쪼개고 인덱스를 지우는 방법도 한번 생각해보세요.

    2. 필요없는 ROW를 삭제한다.

    저는 이미 인덱스는 삭제한 상태이며 이제는 ROW 갯수를 줄여가는 중입니다.

    지금은 1을 수집하지 않고 있지만 앞으로는 10이하를 수집 하지 않을 수도 있습니다.

    그렇게 되면 용량이 더 많이 확보되겠죠.

    10이하를 삭제할 경우 만약2GB용량이 200MB 정도의 용량이 된다면 과감하게 삭제 할 지도 모르겠습니다.

    한번 10이하를 몽땅 삭제 해보아야겠네요.

    Query OK, 22289399 rows affected (15 min 9.646 sec)

    1을 삭제 했더니 22,289,399개의 ROW가 삭제되었네요.

    총 갯수가 7천만개 정도 였으니… 대략 30%가 삭제된듯 합니다.

    1,2,3,4,5 총 5개의 항목이니 5이하를 삭제할 경우 대략 처음대비 70%정도의 용량이 늘어날 것으로 예상됨니다.

    명령어 입력을 잘 못하여 counter < 5 이렇게 넣었네요.

    이미 1항목이 삭제된 상태였고 5미만 처리 해서 5가 포함되지 않아 2,3,4 이렇게 3항목이 추가로 삭제 되었습니다.

    Query OK, 16883723 rows affected (10 min 33.614 sec)

    16,883,723건의 ROW가 삭제되었습니다.

    이번에는 아예 10 이하로 지정했습니다.

    1,2,3,4까지 삭제된 상태가 31,608,565개라면 10 이하를 삭제 할 경우 5,6,7,8,9,10 이렇게 총 6개 항목의 ROW가 삭제됩니다.

    Query OK, 9852316 rows affected (6 min 51.217 sec)

    생각한 수치만큼 많이 삭제되지는 않았네요.

    9,852,316건의 ROW가 삭제되었습니다.

    만약 ROW를 삭제 할 수 없는 상태라면 이렇게 고민을 해보시기 바랍니다.

    MAX 수치 또는 MIN 수치 값이 분명 존재할겁니다.

    혹은 가장 많은 수치를 반복적으로 수집되는 ROW가 많이 있다면 그 ROW만 제거하는 겁니다.

    그리고 제거된 날짜, INDEX 마다 체크하여 그 값이 존재한다고 가정하고 결과물을 만들어내는거죠.

    그 하나의 통일된 ROW만 제거 되더라도 용량 확보가 엄청 많이 됩니다.

  • c# date format yyyy-mm-dd 시간 string 날짜 포맷

    c# date format yyyy-mm-dd 시간 string 날짜 포맷

    
                string dateFormat1 = DateTime.Now.ToString("yyyyMMdd");
                string dateFormat2 = DateTime.Now.ToString("yyyyMMdd HHmmss");
                string dateFormat3 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
    
                MessageBox.Show(dateFormat1);
                MessageBox.Show(dateFormat2);
                MessageBox.Show(dateFormat3);
    

    public class ToStringExample4
    {
       public static void Main1()
       {
          // Create an array of all supported standard date and time format specifiers.
          string[] formats = {"d", "D", "f", "F", "g", "G", "m", "o", "r",
                              "s", "t", "T", "u", "U", "Y"};
          // Create an array of four cultures.
          CultureInfo[] cultures = {CultureInfo.GetCultureInfo("de-DE"),
                                    CultureInfo.GetCultureInfo("en-US"),
                                    CultureInfo.GetCultureInfo("es-ES"),
                                    CultureInfo.GetCultureInfo("fr-FR")};
           // Define date to be displayed.
          DateTime dateToDisplay = new DateTime(2008, 10, 31, 17, 4, 32);
    
          // Iterate each standard format specifier.
          foreach (string formatSpecifier in formats)
          {
             foreach (CultureInfo culture in cultures)
                Console.WriteLine("{0} Format Specifier {1, 10} Culture {2, 40}",
                                  formatSpecifier, culture.Name,
                                  dateToDisplay.ToString(formatSpecifier, culture));
             Console.WriteLine();
          }
       }
    }
    
    // The example displays the following output:
    //    d Format Specifier      de-DE Culture                               31.10.2008
    //    d Format Specifier      en-US Culture                               10/31/2008
    //    d Format Specifier      es-ES Culture                               31/10/2008
    //    d Format Specifier      fr-FR Culture                               31/10/2008
    //    
    //    D Format Specifier      de-DE Culture                Freitag, 31. Oktober 2008
    //    D Format Specifier      en-US Culture                 Friday, October 31, 2008
    //    D Format Specifier      es-ES Culture           viernes, 31 de octubre de 2008
    //    D Format Specifier      fr-FR Culture                 vendredi 31 octobre 2008
    //    
    //    f Format Specifier      de-DE Culture          Freitag, 31. Oktober 2008 17:04
    //    f Format Specifier      en-US Culture         Friday, October 31, 2008 5:04 PM
    //    f Format Specifier      es-ES Culture     viernes, 31 de octubre de 2008 17:04
    //    f Format Specifier      fr-FR Culture           vendredi 31 octobre 2008 17:04
    //    
    //    F Format Specifier      de-DE Culture       Freitag, 31. Oktober 2008 17:04:32
    //    F Format Specifier      en-US Culture      Friday, October 31, 2008 5:04:32 PM
    //    F Format Specifier      es-ES Culture  viernes, 31 de octubre de 2008 17:04:32
    //    F Format Specifier      fr-FR Culture        vendredi 31 octobre 2008 17:04:32
    //    
    //    g Format Specifier      de-DE Culture                         31.10.2008 17:04
    //    g Format Specifier      en-US Culture                       10/31/2008 5:04 PM
    //    g Format Specifier      es-ES Culture                         31/10/2008 17:04
    //    g Format Specifier      fr-FR Culture                         31/10/2008 17:04
    //    
    //    G Format Specifier      de-DE Culture                      31.10.2008 17:04:32
    //    G Format Specifier      en-US Culture                    10/31/2008 5:04:32 PM
    //    G Format Specifier      es-ES Culture                      31/10/2008 17:04:32
    //    G Format Specifier      fr-FR Culture                      31/10/2008 17:04:32
    //    
    //    m Format Specifier      de-DE Culture                              31. Oktober
    //    m Format Specifier      en-US Culture                               October 31
    //    m Format Specifier      es-ES Culture                            31 de octubre
    //    m Format Specifier      fr-FR Culture                               31 octobre
    //    
    //    o Format Specifier      de-DE Culture              2008-10-31T17:04:32.0000000
    //    o Format Specifier      en-US Culture              2008-10-31T17:04:32.0000000
    //    o Format Specifier      es-ES Culture              2008-10-31T17:04:32.0000000
    //    o Format Specifier      fr-FR Culture              2008-10-31T17:04:32.0000000
    //    
    //    r Format Specifier      de-DE Culture            Fri, 31 Oct 2008 17:04:32 GMT
    //    r Format Specifier      en-US Culture            Fri, 31 Oct 2008 17:04:32 GMT
    //    r Format Specifier      es-ES Culture            Fri, 31 Oct 2008 17:04:32 GMT
    //    r Format Specifier      fr-FR Culture            Fri, 31 Oct 2008 17:04:32 GMT
    //    
    //    s Format Specifier      de-DE Culture                      2008-10-31T17:04:32
    //    s Format Specifier      en-US Culture                      2008-10-31T17:04:32
    //    s Format Specifier      es-ES Culture                      2008-10-31T17:04:32
    //    s Format Specifier      fr-FR Culture                      2008-10-31T17:04:32
    //    
    //    t Format Specifier      de-DE Culture                                    17:04
    //    t Format Specifier      en-US Culture                                  5:04 PM
    //    t Format Specifier      es-ES Culture                                    17:04
    //    t Format Specifier      fr-FR Culture                                    17:04
    //    
    //    T Format Specifier      de-DE Culture                                 17:04:32
    //    T Format Specifier      en-US Culture                               5:04:32 PM
    //    T Format Specifier      es-ES Culture                                 17:04:32
    //    T Format Specifier      fr-FR Culture                                 17:04:32
    //    
    //    u Format Specifier      de-DE Culture                     2008-10-31 17:04:32Z
    //    u Format Specifier      en-US Culture                     2008-10-31 17:04:32Z
    //    u Format Specifier      es-ES Culture                     2008-10-31 17:04:32Z
    //    u Format Specifier      fr-FR Culture                     2008-10-31 17:04:32Z
    //    
    //    U Format Specifier      de-DE Culture       Freitag, 31. Oktober 2008 09:04:32
    //    U Format Specifier      en-US Culture      Friday, October 31, 2008 9:04:32 AM
    //    U Format Specifier      es-ES Culture   viernes, 31 de octubre de 2008 9:04:32
    //    U Format Specifier      fr-FR Culture        vendredi 31 octobre 2008 09:04:32
    //    
    //    Y Format Specifier      de-DE Culture                             Oktober 2008
    //    Y Format Specifier      en-US Culture                             October 2008
    //    Y Format Specifier      es-ES Culture                          octubre de 2008
    //    Y Format Specifier      fr-FR Culture                             octobre 2008

    using System;
    using System.Globalization;
    
    public class MainClass
    {
        public static void Main(string[] args)
        {
            DateTime dt = DateTime.Now;
            String[] format = {
                "d", "D",
                "f", "F",
                "g", "G",
                "m",
                "r",
                "s",
                "t", "T",
                "u", "U",
                "y",
                "dddd, MMMM dd yyyy",
                "ddd, MMM d \"'\"yy",
                "dddd, MMMM dd",
                "M/yy",
                "dd-MM-yy",
            };
            string date;
            for (int i = 0; i < format.Length; i++)
            {
                date = dt.ToString(format[i], DateTimeFormatInfo.InvariantInfo);
                Console.WriteLine(string.Concat(format[i], " :", date));
            }
    
            /** Output.
             *
             * d :08/17/2000
             * D :Thursday, August 17, 2000
             * f :Thursday, August 17, 2000 16:32
             * F :Thursday, August 17, 2000 16:32:32
             * g :08/17/2000 16:32
             * G :08/17/2000 16:32:32
             * m :August 17
             * r :Thu, 17 Aug 2000 23:32:32 GMT
             * s :2000-08-17T16:32:32
             * t :16:32
             * T :16:32:32
             * u :2000-08-17 23:32:32Z
             * U :Thursday, August 17, 2000 23:32:32
             * y :August, 2000
             * dddd, MMMM dd yyyy :Thursday, August 17 2000
             * ddd, MMM d "'"yy :Thu, Aug 17 '00
             * dddd, MMMM dd :Thursday, August 17
             * M/yy :8/00
             * dd-MM-yy :17-08-00
             */
        }
    }

    output 항목을 보고 원하는 문자열 만들면 됩니다.

  • 네이버 블로그 방문자 아이디 확인 알고리즘 패턴 공개

    네이버 블로그 방문자 아이디 확인 알고리즘 패턴 공개

    네이버 블로그 방문자 아이디 한개씩 분석 확인 하기 위한 패턴을 공개합니다.

    그리 어려운 부분은 아니지만 어떻게 활용 하냐에 따라서 중요한 정보가 됩니다.

    아래 패턴에서 가장 중요한 항목은 Pattern 변수 항목이겠죠.

    저 혼자서 몰래 사용하고 있는

    네이버 블로그 방문자 아이디 확인 알고리즘

    보실 분들은 아래 소스 코드를 보고

    그대로 따라 만들 수 있습니다.

    [coupang]

    
    // 방문자 구분
    // 패턴 분석
    
    // <visitorcnt id="20230320" cnt="1"/>
    // 오늘 날짜 문자열 생성하여 -4일까지 분석
    
    //string pattern = "[<]visitorcnt id=[\"][0-9]{8}[\"] cnt=[\"][0-9]{1,7}[\"][/].*[>]";
    string pattern = "[<]visitorcnt id=[\"](?<dateString>[0-9]{8})[\"] cnt=[\"](?<cntString>[0-9]{1,7})[\"].*[>]";
    
    MatchCollection matches = Regex.Matches(resultValue, pattern);
    
    foreach (Match match in matches)
    {
    	listBox_blogid_count.Invoke((MethodInvoker)delegate ()
    	{
    		Thread.Sleep(1000);
    		listBox_blogid_count.Items.Clear();
    		listBox_blogid_count.Items.Add(match.Groups["dateString"]);
    		listBox_blogid_count.Items.Add(match.Groups["cntString"]);
    	});
    }
    

    방문자 링크에서 받아온 XML 문서를 분석하여 날짜와 방문자 수를 정확하게 알 수 있는 알고리즘입니다.

    이 알고리즘을 기반으로 블로그 지수를 확인 할 수 있게 됩니다.

    블로그 방문자 에이전트 v 3.1.1 업데이트 중인데요.

    [coupang_end]

    기존 7~8년전에 개발한 모델에 최신 기능을 추가하려고 소스코드를 확인해보았더니… 어후… ㅎㅎ 너무 고전 코드더군요.

    이 프로그램은 따로 공개를 하지 자체적인 시스템에서 동작하다보니 결과물 (빅데이터) 만들때 사용하고 있습니다.

    이 툴을 활용할 수 있는 방법으로는 내 블로그 방문자수 실시간 확인 하는 방법이 있습니다.

    https://visitor.munhoyoung.com/

    그리고 방문자수를 활용한 블로그 지수 확인 사이트도 만들 수 있죠.

    https://sta.tion.co.kr/blog_visit/

    블로그 지수가 궁금하거나 블로그 지수에 맞는 키워드를 찾아내고 싶다면 아래 사이트를 이용하시면 됩니다.

    네이버 블로그 방문자 아이디별로 확인 후 빅데이터 데이터마이닝 한 것이 현재 우리가 사용하고 있는 블로그 지수 정보입니다.

  • phpmyadmin config.inc.php 설정 자동 다운로드 스크립트

    phpmyadmin config.inc.php 설정 자동 다운로드 스크립트

    phpmyadmin config.inc.php 설정

    phpMyAdmin 설정을 매번 서버 만들때마다 해야 합니다.

    그래서 이를 자동으로 서버 생성시 만들어지도록 하였습니다.

    #phpmyadmin 폴더에서 아래 명령어를 입력하세요
    #주의!! 새로 설치했을때만 적용하세요.
    
    cd /var/www/phpMyAdmin
    rm -rf config.inc.php
    rm -rf config.sample.inc.php
    wget -O config.inc.php https://vlog.tion.co.kr/html/phpmyadmin/config.inc.php?isDownload=1
    ll
    
    

    phpMyAdmin 5.x.x version config.inc.php file DOWNLOAD

    다로 파일 설정만 필요하면 아래 코드를 그대로 복사하여 사용하면 됩니다.

    <?php
    /* vim: set expandtab sw=4 ts=4 sts=4: */
    /**
    * phpMyAdmin sample configuration, you can use it as base for
    * manual configuration. For easier setup you can use setup/
    *
    * All directives are explained in documentation in the doc/ folder
    * or at <https://docs.phpmyadmin.net/>.
    *
    * @package PhpMyAdmin
    */
    declare(strict_types=1);

    /**
    * This is needed for cookie based authentication to encrypt password in
    * cookie. Needs to be 32 chars long.
    */
    $cfg[‘blowfish_secret’] = ‘gzOatgMa2i5BVE5F2YkM.Tx5fg@YxuBd‘;

    /**
    * Servers configuration
    */
    $i = 0;

    /**
    * First server
    */
    $i++;
    /* Authentication type */
    $cfg[‘Servers’][$i][‘auth_type’] = ‘cookie’;
    /* Server parameters */
    $cfg[‘Servers’][$i][‘host’] = ‘localhost’;
    $cfg[‘Servers’][$i][‘compress’] = false;
    $cfg[‘Servers’][$i][‘AllowNoPassword’] = false;

    /**
    * phpMyAdmin configuration storage settings.
    */

    /* User used to manipulate with storage */
    // $cfg[‘Servers’][$i][‘controlhost’] = ”;
    // $cfg[‘Servers’][$i][‘controlport’] = ”;
    // $cfg[‘Servers’][$i][‘controluser’] = ‘pma’;
    // $cfg[‘Servers’][$i][‘controlpass’] = ‘pmapass’;

    /* Storage database and tables */
    // $cfg[‘Servers’][$i][‘pmadb’] = ‘phpmyadmin’;
    // $cfg[‘Servers’][$i][‘bookmarktable’] = ‘pma__bookmark’;
    // $cfg[‘Servers’][$i][‘relation’] = ‘pma__relation’;
    // $cfg[‘Servers’][$i][‘table_info’] = ‘pma__table_info’;
    // $cfg[‘Servers’][$i][‘table_coords’] = ‘pma__table_coords’;
    // $cfg[‘Servers’][$i][‘pdf_pages’] = ‘pma__pdf_pages’;
    // $cfg[‘Servers’][$i][‘column_info’] = ‘pma__column_info’;
    // $cfg[‘Servers’][$i][‘history’] = ‘pma__history’;
    // $cfg[‘Servers’][$i][‘table_uiprefs’] = ‘pma__table_uiprefs’;
    // $cfg[‘Servers’][$i][‘tracking’] = ‘pma__tracking’;
    // $cfg[‘Servers’][$i][‘userconfig’] = ‘pma__userconfig’;
    // $cfg[‘Servers’][$i][‘recent’] = ‘pma__recent’;
    // $cfg[‘Servers’][$i][‘favorite’] = ‘pma__favorite’;
    // $cfg[‘Servers’][$i][‘users’] = ‘pma__users’;
    // $cfg[‘Servers’][$i][‘usergroups’] = ‘pma__usergroups’;
    // $cfg[‘Servers’][$i][‘navigationhiding’] = ‘pma__navigationhiding’;
    // $cfg[‘Servers’][$i][‘savedsearches’] = ‘pma__savedsearches’;
    // $cfg[‘Servers’][$i][‘central_columns’] = ‘pma__central_columns’;
    // $cfg[‘Servers’][$i][‘designer_settings’] = ‘pma__designer_settings’;
    // $cfg[‘Servers’][$i][‘export_templates’] = ‘pma__export_templates’;

    /**
    * End of servers configuration
    */

    /**
    * Directories for saving/loading files from server
    */
    $cfg[‘UploadDir’] = ”;
    $cfg[‘SaveDir’] = ”;
    $cfg[‘TempDir’] = ‘/tmp’;
    /**
    * Whether to display icons or text or both icons and text in table row
    * action segment. Value can be either of ‘icons’, ‘text’ or ‘both’.
    * default = ‘both’
    */
    //$cfg[‘RowActionType’] = ‘icons’;

    /**
    * Defines whether a user should be displayed a “show all (records)”
    * button in browse mode or not.
    * default = false
    */
    //$cfg[‘ShowAll’] = true;

    /**
    * Number of rows displayed when browsing a result set. If the result
    * set contains more rows, “Previous” and “Next”.
    * Possible values: 25, 50, 100, 250, 500
    * default = 25
    */
    //$cfg[‘MaxRows’] = 50;

    /**
    * Disallow editing of binary fields
    * valid values are:
    * false allow editing
    * ‘blob’ allow editing except for BLOB fields
    * ‘noblob’ disallow editing except for BLOB fields
    * ‘all’ disallow editing
    * default = ‘blob’
    */
    //$cfg[‘ProtectBinary’] = false;

    /**
    * Default language to use, if not browser-defined or user-defined
    * (you find all languages in the locale folder)
    * uncomment the desired line:
    * default = ‘en’
    */
    //$cfg[‘DefaultLang’] = ‘en’;
    //$cfg[‘DefaultLang’] = ‘de’;

    /**
    * How many columns should be used for table display of a database?
    * (a value larger than 1 results in some information being hidden)
    * default = 1
    */
    //$cfg[‘PropertiesNumColumns’] = 2;

    /**
    * Set to true if you want DB-based query history.If false, this utilizes
    * JS-routines to display query history (lost by window close)
    *
    * This requires configuration storage enabled, see above.
    * default = false
    */
    //$cfg[‘QueryHistoryDB’] = true;

    /**
    * When using DB-based query history, how many entries should be kept?
    * default = 25
    */
    //$cfg[‘QueryHistoryMax’] = 100;

    /**
    * Whether or not to query the user before sending the error report to
    * the phpMyAdmin team when a JavaScript error occurs
    *
    * Available options
    * (‘ask’ | ‘always’ | ‘never’)
    * default = ‘ask’
    */
    //$cfg[‘SendErrorReports’] = ‘always’;

    /**
    * You can find more configuration options in the documentation
    * in the doc/ folder or at <https://docs.phpmyadmin.net/>.
    */

  • cmd 배치파일 프로그램 실행 후 자동 종료

    cmd 배치파일 프로그램 실행 후 자동 종료

    cmd 배치파일 이용해서 프로그램을 실행하면 프로그램이 종료될때까지 cmd 창이 그대로 떠 있습니다.

    이를 그대로 놓고 사용해도 되지만 프로그램 화면 위에 cmd 창이 떠 있어서 불편할때가 있죠.

    그때 cmd 명령어를 call 대신에 start 를 이용하여 해결 할 수 있습니다.

    start "" "실행파일명.exe"

    call 명령어로도 해결되지 않고 단순 start 명령어러도 해결이 되지 않습니다.

    start 뒤에 꼭 따옴표 2개 작성해주시고 그다음에 실행 파일명 적으면 됩니다.

    재부팅 후에 자동으로 프로그램이 실행되며 cmd 창은 프로그램 실행과 동시에 자동 종료됩니다.

    해결 완료!!

  • 윈도우 시작시 프로그램 자동실행 c# 제작 소스코드

    윈도우 시작시 프로그램 자동실행 c# 제작 소스코드

    윈도우 시작시 프로그램 자동실행 소스코드

    보통 체크박스를 이용하여 윈도우 시작시 프로그램이 자동으로 실행하게 할껀지 아닐지 여부를 선택합니다.

    이렇게 체크박스를 만들어서 체크를 할 경우 윈도우시작할때 바로 프로그램이 실행되도록 할 수 있습니다.

    윈도우 시작시 프로그램 자동실행 소스코드

    // init()
    
                try
                {
                    if (ReadValue("info", "checkBox_윈도우자동시작") != null)
                    {
                        string text = ReadValue("info", "checkBox_윈도우자동시작");
    
                        if (text == "true")
                        {
                            checkBox_윈도우자동시작.Checked = true;
    
                        }
                        else
                        {
                            checkBox_윈도우자동시작.Checked = false;
                        }
    
                    }
    
                }
                catch { }
    
    
    // checkbox click
    
            RegistryKey runRegKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
    
            private void checkBox_윈도우자동시작_CheckedChanged(object sender, EventArgs e)
            {
                string 프로그램명 = string.Format("{0}", System.IO.Path.GetFileName(Application.ExecutablePath));
                if (checkBox_윈도우자동시작.Checked)
                {
                    runRegKey.SetValue(프로그램명,string.Format("{0}{1}", System.AppDomain.CurrentDomain.BaseDirectory, System.IO.Path.GetFileName(Application.ExecutablePath)
    ));
                    WriteValue("info", "checkBox_윈도우자동시작", "true");
                }
                else
                {
                    runRegKey.DeleteValue(프로그램명, false);
                    WriteValue("info", "checkBox_윈도우자동시작", "false");
                }
            }

    사실 위의 소스코드에서 가장 중요한 부분은 바로 RegistryKey 항목입니다.

    RegistryKey runRegKey = Registry.CurrentUser.OpenSubKey(“SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run”, true);

    레지스트리키에다가 현재 프로그램을 등록하는것이죠.

    윈도우 7, 8, 10, 11 시작프로그램 항목에 넣어서 할수도 있지만 조금 다른 부분은 바로가기 형식의 파일 링크를 걸어두는게 아닌 레지스트리키에 프로그램 경로를 String(문자열) 형태로 입력하는 방식입니다.

    이제 언제든지 컴퓨터를 켤때마다 자동으로 프로그램이 실행됩니다.

  • c# 외부 ip 가져오기 로컬 ipv4 아이피 함수 Function

    c# 외부 ip 가져오기 로컬 ipv4 아이피 함수 Function

    C 프로그래밍 언어와 C++, C# 등 로컬 영역에서 동작하는 프로그램으로는 자신의 외부 아이피를 확인 할 수 없습니다. 특히 공유기를 이용하고 있고 사설 아이피로 IP를 할당 받았다면 더더욱 알수 없죠.

    기껏 알수 있는 아이피는 192.168.0.1 수준의 사설 아이피뿐입니다.

    C# 외부 로컬 ipv4 아이피를 알기 위해서는 아래 함수를 이용하면 바로 확인 할 수 있습니다.

    인터넷이 꼭 연결되어져 있어야 합니다.

    public static IPAddress GetExternalIp()
    {
    	string ip = string.Empty;
    
    	try
    	{
    		string sourceURL = string.Empty;
    		sourceURL = string.Format("https://api.tion.kr");
    
    		WebClient client = new WebClient();
    		client.Encoding = Encoding.UTF8;
    
    		string data = client.DownloadString(string.Format("https://api.tion.kr"));
    
    
    		string pattern = "(<myip>)(?<ip>[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}?)(</myip>)";
    		MatchCollection matches = Regex.Matches(data, pattern);
    
    		foreach (Match match in matches)
    		{
    			if (match.Groups["ip"].Length > 0)
    			{
    				//IP 정상적으로 나오는지 확인하는부분
    				//MessageBox.Show(match.Groups["ip"].Value);
    				ip = match.Groups["ip"].Value;
    			}
    		}
    	}
    	catch (Exception)
    	{
    
    	}
    
    	IPAddress externalIp = IPAddress.Parse(ip); 
    
    	return externalIp;
    
    }

    위의 함수 소스코드는 https://api.tion.kr 사이트에서 제공하고있습니다.

    위의 사이트도 제가 직접 만든 사이트입니다.

    실제로 C#에서 아이피를 가져와야할 일이 많다보니 2013년부터 만들어서 앞으로 계속 사용하기 위해서 만든거라 개발하실때 만드시더라도 특별한 일 없는이상 위의 도메인을 유지할겁니다.

    2017년도에 기간연장 10년치 최고 결재라서 10년치 결재했는데 벌써 4년 남았네요.

    2년정도 남았을때 다시 10년 기간 연장 해놓겠습니다.

    직접 C# 프로그램으로 제작해보았습니다.

    아래는 제가 C#으로 직접 만든 프로그램 입니다.

    c# 외부 ip 가져오기 소스코드

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace ESXi_IP_Monitoring
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                label_ip.Text = String.Format("{0}", GetExternalIp());
            }
    
            public static IPAddress GetExternalIp()
            {
                string ip = string.Empty;
    
                try
                {
                    string sourceURL = string.Empty;
                    sourceURL = string.Format("https://api.tion.kr");
    
                    WebClient client = new WebClient();
                    client.Encoding = Encoding.UTF8;
    
                    string data = client.DownloadString(string.Format("https://api.tion.kr"));
    
    
                    string pattern = "(<myip>)(?<ip>[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}?)(</myip>)";
                    MatchCollection matches = Regex.Matches(data, pattern);
    
                    foreach (Match match in matches)
                    {
                        if (match.Groups["ip"].Length > 0)
                        {
                            //IP 정상적으로 나오는지 확인하는 부분
                            //MessageBox.Show(match.Groups["ip"].Value);
                            ip = match.Groups["ip"].Value;
                        }
                    }
                }
                catch (Exception)
                {
    
                }
    
                IPAddress externalIp = IPAddress.Parse(ip);
    
                return externalIp;
    
            }
        }
    }
    

    외부 IP를 잘 가져오는군요.

    저는 이렇게 외부 IP를 자동으로 가져와서 ESXi 방화벽에 자동추가하는 시스템을 만들고 있습니다.

    외부 어느지역에서도 ESXi 서버에 자유롭게 자동으로 접속하기 위한 시스템이죠.

    방화벽으로 특정 IP만 접속 할 수 있도록 만들고 위의 프로그램으로 1분동안 접속 가능하도록 만들고 있습니다.

    노트북을 끄는 순간 1분후에 자동으로 제가 사용하던 IP도 차단이 되는 시스템이죠.

    보안으로 인해서 작년 말부터 고생을 하고 있어 이부분을 확실히 하고 있습니다.

    보안이 필요하신 분들 계시면 말씀주세요.

  • 윈도우 wget 대체 방법 vmware esxi 파일 공유 소스코드

    윈도우 wget 대체 방법 vmware esxi 파일 공유 소스코드

    윈도우 10, 11에서 VMWARE 강제 재부팅 문제 발생

    vmware 사용할때에는 자체 file share 기능을 이용하여 host 폴더를 지정하여 guest vm에서 같은 폴더를 지정하여 사용하였습니다. 그런데 host pc에서 최근들어 강제로 업데이트 되면서 vmware workstation 버전 상관없이 강제 재부팅이 자주 일어나고 있습니다.

    이를 해결하기 위해서 xenserver, vmware esxi, 기타 등등 linux 기반에서 vm을 관리하는 방법이 윈도우 10 강제 재부팅을 막을 수 있는 유일한 방법이더군요.

    게중에는 윈도우10, 11 업데이트를 막으면 된다는 글들이 많지만 실제로 수도 없이 해보았고 업데이트 안될시 불이익 등등 다 따져보았을때 운영체제를 바꾸는것이 정답이더군요.

    결국 ESXi 서버를 도입하게 되었습니다.

    그런데 이때 문제가 발생하더군요.

    기존에 vmware workstation 에서는 위에서 이미 말씀드린바 공유폴더를 지정할수 있었습니다.

    ESXi 와 Xenserver 와 같은 시스템에서는 그러한 부분들이 잘 되어 있지 않아 (제가 모를수도 있고요) 직접 guest vm마다 공유폴더를 만들어서 사용하려합니다.

    이렇다보니 윈도우7, 윈도우10 guest vm에서 파일을 강제로 다운받아야 하는데 리눅스처럼 wget 기능이 없어 윈도우 wget 대체 프로그램을 찾다가 파워쉘이 유일한 방법이더군요.

    그래서 제가 직접 만들게 된겁니다.

    wget.exe 파일 다운로드

    아래 파워쉘 방법은 그냥 참고 하시고요.

    매번 배치파일 만들어서 매번 저 명령어를 외울수도 없고…

    powershell "(New-Object System.Net.WebClient).DownloadFile('https://vlog.tion.co.kr/app/wget.exe','C:\Windows\System32\wget.exe')"
    
    powershell "(New-Object System.Net.WebClient).DownloadFile('https://URI','Filename.zip')"

    윈도우 wget 대체 소스코드 공유

    C#으로 만들었으며 소스코드는 그대로 올려놓을테니 저처럼 직접 필요한분들은 C#으로만들어 쓰세요.

    wget.exe 파일 다운로드

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    using static System.Net.Mime.MediaTypeNames;
    
    namespace wget
    {
        internal class Program
        {
            static void help()
            {
                Console.WriteLine("wget version: 1.0");
                Console.WriteLine("wget: missing URL");
                Console.WriteLine("Usage: wget https://vlog.tion.co.kr/app/wget.exe");
                Console.WriteLine("");
                Console.WriteLine("Try `wget --help` for help");
                Console.WriteLine("");
                Console.WriteLine("made by 리눅스맨 2023-02-24 vlog.tion.co.kr");
            }
            static void Main(string[] args)
            {
    
                if (args.Length == 0)
                {
                    help();
                }
                else
                {
                    switch (args.Length)
                    {
                        case 1:
    
                            if (args[0].Contains("http"))
                            {
                                Uri uri = new Uri(args[0]);
    
                                string fileName = null;
                                string[] uriSegments = uri.Segments;
                                int indexSegment = 0;
                                foreach (string getFileName in uriSegments)
                                {
                                    if (++indexSegment == uriSegments.Length)
                                    {
                                        //Console.WriteLine(getFileName);
                                        fileName = WebUtility.UrlDecode(getFileName.Trim());
                                    }
    
                                }
    
                                string remoteUri = uri.OriginalString;
                                string myStringWebResource = remoteUri;
                                // Create a new WebClient instance.
                                WebClient myWebClient = new WebClient();
                                // Concatenate the domain with the Web resource filename.
                                Console.WriteLine("Downloading File \"{0}\" from \"{1}\" .......\n\n", fileName, myStringWebResource);
                                // Download the Web resource and save it into the current filesystem folder.
    
                                myWebClient.DownloadFile(myStringWebResource, fileName);
                                Console.WriteLine("Successfully Downloaded File \"{0}\" from \"{1}\"", fileName, myStringWebResource);
                                Console.WriteLine("\nDownloaded file saved");
    
                            }
                            else if (args[0].Equals("--help"))
                            {
                                
                            }
                            else
                            {
                                help();
                                
                            }
    
                            break;
                    }
                }
                
            }
        }
    }
    

    이제 필요한 파일을 웹서버 하나 만들어서 업로드 하고 필요할때마다 wget.exe 파일 이용해서 다운받으면됩니다.

  • 웹서버 다운 원인 분석 결국 해커가 서버를 해킹

    웹서버 다운 원인 분석 결국 해커가 서버를 해킹

    웹서버 다운 원인 분석중입니다.

    워드프레스 홈페이지가 다운 되었다고 메일이 날라와서 그 시간대 로그를 확인해보았습니다.

    2023년 2월 17일 (금일 아침) 7시 47분 ~ 8시 8분 대략 22분정도 다운이 되었습니다.

    위의 파일은 serverChecker.php 파일을 1분마다 다운로드 받는것인데 제가 만들어놓은 스크립트가 있습니다.

    serverChecker.php 접속해서 자동으로 로그를 기록합니다.

    그걸 사용하시면 언제 웹서버가 다운되었는 정확하게 알 수 있습니다.

    파일 크키가 0일때 서버가 다운된것이므로 파일 크기 0일때를 조사해보았습니다.

    ll -SSh /root/_TION/_logs_tionServerMonitor/ | grep ^-

    3일정도를 분단위로 로그를 저장하고 있는데 하루에 한번씩 20분정도 서버가 멈추는 것으로 파악되었습니다.

    그리고 의문의 한가지가 있는데요.

    같은 시각 다른 서버에서도 동일한 흔적이 있었습니다.

    같은서버가 아님에도 불구하고 같은 시간 동일하게 서버가 다운되었습니다.

    그래서 로그를 확인해보니… 해킹시도로 인한 서비스 다운이 된듯합니다.

    최근에 관리자 접속이 계속 잠기고 로그인 할 수 없었는데 해커 2명정도가 계속 서버에 붙어서 로그인 시도를 하고 있었네요. 안타깝습니다.

    지금 확인하고 있는 가운데에도 계속 저렇게 해킹시도를 하고 있으니…

    이벤트 로그에서 해킹시도가 명백해졌으므로 IP 차단으로 해결할 문제는 아닌듯하고

    서버 root 접속 시도하는 모든 아이피를 자동으로 차단하도록 해야될꺼같단 생각이 들었습니다.

    아마존 EC2 운영은 보안서버가 EC2 서버 앞단에 있어서 방화벽으로IP를 제어할수 있지만

    ESXi, Xenserver 같은 개인서버를 운영할 경우 방화벽 단계가 없다보니 애시당초 로그인 자체를 못하게 막아야합니다.

    로그인 아이디 단 1번이라도 틀리면 접속을 못하도록 막아버려야 할꺼같습니다.

    ESXi 서버를 운영할 경우에는 아래 항목을 찾아서 변경합니다.

    Security.AccountLockFailures
    사용자 계정을 잠그기 전 허용되는 최대 로그인 실패 횟수입니다. 0은 계정 잠금을 사용하지 않습니다.
    5
    
    Security.AccountUnlockTime
    허용되는 최대 로그인 시도 실패 횟수를 초과한 후 사용자의 계정을 잠그는 기간(초)입니다.
    900
    

    저는 숫자를 900 기본값에서 999999999초로 변경하였습니다.

    31년동안 접속못하도록 막는 수치입니다.

    해커 IP가 31년 차단 당했네요.

    우리 31년 후에 만나자!~

    안녕.

    동시에 방화벽 설정에 접속 허용 IP를 지정해버렸습니다.

    완벽하게 접속하지 못하는것을 확인하였습니다.

    혹시나 유동IP 바뀌면 안되므로 고정아이피 3개랑 유동아이피 3개를 넣었습니다.

    바뀌더라도 어느 하나는 접속 가능하겠죠 ㅎㅎ

    해결 완료!

  • 티온 서버모니터링 사용방법

    티온 서버모니터링 사용방법

    티온 웹서버모니터링

    티온 서버모니터링 사용방법

    서버를 다수 운영하다보니 각 서버마다 부하, 상태를 확인하기 어렵더군요.

    그래서 관련 웹서버 모니터링 서비스를 찾아보았지만 제 맘에 드는게 없어서 직접 만들었습니다.

    우선 파이썬3 버전이 설치가 되어져있어야 합니다.

    파이썬3 설치에 관련해서는 아래 링크를 참고해주세요.

    파이썬3 버전이 설치되었다면 아래 명령어를 그대로 복사 붙여넣기 하면됩니다.

    mkdir /root/_TION
    cd /root/_TION
    wget https://vlog.tion.co.kr/python/tionServerMonitoring.tar
    tar xvf tionServerMonitoring.tar
    rm -rf tionServerMonitoring.tar
    echo "python3 /root/_TION/tionServerMonitoring/memcheck_httpd_restart.py" > /tionServerMonitoring.sh
    chmod 701 /tionServerMonitoring.sh
    
    
    (crontab -l 2>/dev/null; echo "*/1 * * * * /tionServerMonitoring.sh") | crontab
    
    /tionServerMonitoring.sh
    
    ls -a
    

    위의 명령어를 그대로 서버에 SSH 프로그램을 이용하여 복사붙여넣기를 하면 python/tionServerMonitoring.tar 파일을 다운받고 그 파일을 압축풀어서 python3 명령어로 실행을 하게됩니다.

    python3: command not found

    파이썬3를 설치했음에도 불구하고 위처럼 나타나면 심볼릭을 잡아주시기 바랍니다.

    ln -s /usr/bin/python3.8 /usr/bin/python3

    이제 python3 명령어로 잘 실행이 되는군요.

    이제 다시 [ /tionServerMonitoring.sh ] 쉘스크립트를 실행해보겠습니다.

    위에서 이미 설치를 하였기에 다시 또 설치할 필요는 없습니다.

    괜히 crontab 항목에 1분마다 서버체크하는 항목만 더 추가되니 2번이상 설치하신분들은 꼭 crontab -e 항목을 확인하셔서 중복된 체킹을 제거해주세요.

    [root@amzn2 _TION]# /tionServerMonitoring.sh
    Traceback (most recent call last):
    File “/root/_TION/tionServerMonitoring/memcheck_httpd_restart.py”, line 1, in
    import psutil
    ModuleNotFoundError: No module named ‘psutil’

    이번에는 psutil 이라는 모듈이 없다고 나올겁니다.

    pip 명령어를 이용하여 psutil, stdin모듈을 설치해주세요

    pip install psutil stdin

    만약 pip 명령어가 없다고 나올 경우

    -bash: pip: command not found

    pip를 설치해야합니다.

    아래 링크에서 pip install 설치를 우선 확인하고 설치해주세요. (이 글 본문에도 링크 아랫쪽에 넣어두긴했습니다)

    1. 파이썬 get-pip.py 파일을 다운받습니다.

    아래 명령어를 입력하여 리눅스 서버에 get-pip.py 파일을 저장합니다.

    curl https://vlog.tion.co.kr/python/get-pip.py -o get-pip.py

    2. get-pip.py 파일을 이용하여 인스톨을 시작합니다.

    python3 get-pip.py

    이제 다시 pip install psutil string 이라고 해주세요

    이제 모든 모듈을 다 설치했습니다.

    이제 다시 [ /tionServerMonitoring.sh ] 쉘스크립트를 실행해보겠습니다.

    [root@amzn2 _TION]# /tionServerMonitoring.sh
    START!!
    MEMORY TOTAL: 960.46MB
    MEMORY USED: 187.34MB
    MEMORY FREE: 380.65MB
    -------------------------------------------------------------------------------------
    MEMORY percent is 34.10%
    MEMORY limit is over 80.00%
    -------------------------------------------------------------------------------------
    DISK TOTAL: 24.99GB
    DISK USED: 2.47GB
    DISK FREE: 22.52GB
    DISK PERCENT 9.90%
    NETWORK SENT: 2.39MB
    NETWORK RECV: 92.30MB
    NETWORK Packets_SENT: 0.03MB
    NETWORK Packets_RECV: 0.10MB
    BOOT_TIME: 2023-02-02 20:44:51
    CPU CORE: 1
    CPU PERCENT: [10.0]
    -------------------------------------------------------------------------------------
    --2023-02-02 21:14:07--  http://3.34.246.177/serverChecker.php?hostname=amzn2&mem_total=960.46MB&mem_used=187.34MB&mem_free=380.65MB&percent=34.10%25&limit=80.00%25&disk_usage_total=24.99GB&disk_usage_used=2.47GB&disk_usage_free=22.52GB&disk_usage_percent=9.90%25&net_io_counters_bytes_sent=2.39MB&net_io_counters_bytes_recv=92.30MB&net_io_counters_packets_sent=0.03MB&net_io_counters_packets_recv=0.10MB&boot_time=2023-02-02%2020:44:51&cpu_count=1&cpu_percent=[10.0]
    Connecting to 3.34.246.177:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 2 [text/html]
    Saving to: ‘/root/_TION/_logs_tionServerMonitor/serverChecker_php_2023-02-02_21:14:06’
    
    100%[===========================================================================================================================================>] 2           --.-K/s   in 0s      
    
    2023-02-02 21:14:07 (135 KB/s) - ‘/root/_TION/_logs_tionServerMonitor/serverChecker_php_2023-02-02_21:14:06’ saved [2/2]
    
    -------------------------------------------------------------------------------------
    INFO: /root/_TION/_logs_tionServerMonitor__ each 3600 minutes
    Checking file to remove in Forder [ /root/_TION/_logs_tionServerMonitor ]
    -------------------------------------------------------------------------------------
    MEMORY percent is 34.10%
    MEMORY limit is over 80.00%
    -------------------------------------------------------------------------------------
                  total        used        free      shared  buff/cache   available
    Mem:           960M        197M        370M        972K        392M        623M
    Swap:            0B          0B          0B
    -------------------------------------------------------------------------------------
    Filesystem      Size  Used Avail Use% Mounted on
    devtmpfs        464M     0  464M   0% /dev
    tmpfs           481M     0  481M   0% /dev/shm
    tmpfs           481M  704K  480M   1% /run
    tmpfs           481M     0  481M   0% /sys/fs/cgroup
    /dev/sda1        25G  2.5G   23G  10% /
    tmpfs            97M     0   97M   0% /run/user/0
    -------------------------------------------------------------------------------------
    [root@amzn2 _TION]# 
    

    위의 결과물이 나왔다면 정상적으로 동작하는것입니다.

    이제 매 1분마다 서버가 잘 동작하는지 확인을 합니다.

    로그 항목이 1분마다 만들어지고 있다면 정상등록된것입니다.

    이제 서버 정보를 findmyserverip.com 으로 보내어 서버 IP와 서버사용량을 실시간 단위로 확인 할 수 있습니다.

    현재는 무료로 사용할수 있으나 사용자가 많이 몰리게되면 1분체크를 5분으로 늘릴겁니다.

    혹시라도 1분 유지를 원하시는 분들은 따로 유료서버를 도입할 계획이니 플랜이 나오면 구입하셔서 사용하시면 됩니다. 지금은 그래프도 만들어야하고 결과 페이지를 만들어야하므로 무료로 사용하실 수 있습니다.

    앞으로만들어질 항목들은 이렇습니다.

    티온 서버모니터링 서비스

    1. 분당 기록되는 정보를 바탕으로 그래프 도표화

    2. 위험수치 (트래픽, 메모리, 디스크 용량 등) 도달시 SMS 문자 발송 서비스

    지금부터 사용하시는 분들에게는 초기맴버로 유료전환시 50% 할인 혜택을 제공해드리겠습니다.

    감사합니다.