[컴] 테스트용 docker network

test / local test / 설치 테스트 / 설치 환경

테스트용 docker network

아래 command 로 실행하자.

docker compose up

bash 접속

docker exec -it testnet-node1-1 bash

network 정보

docker network ls
...
docker network inspect testnet_mybridge

file 정보

# compose.yml
version: '3.8'
services:
    node1:
        build:
            context: .
            dockerfile: ./node.Dockerfile
        # image: redhat/ubi8-init:8.6-798
        volumes:
            - d:\a\prog\docker\testnet\data\:/data/
        ports:
            - "8001:8000"
        environment:
            - CROND_SERVER_URL=http://cronhost:8000/test
        stdin_open: true # docker run -i
        tty: true        # docker run -t
        entrypoint:
            - bin/bash
        networks:
            - mybridge
    node2:
        build:
            context: .
            dockerfile: ./node.Dockerfile
        # image: redhat/ubi8-init:8.6-798
        volumes:
            - d:\a\prog\docker\testnet\data\:/data/
        ports:
            - "8002:8000"
        environment:
            - CROND_SERVER_URL=http://cronhost:8000/test
        stdin_open: true # docker run -i
        tty: true        # docker run -t
        entrypoint:
            - bin/bash
        networks:
            - mybridge
networks:
  mybridge:

# node.Dockerfile
FROM redhat/ubi8-init:8.6-798

RUN dnf install -y iputils
RUN dnf install -y net-tools

그 밖의 tips

# root 이외 계정으로 실행해야만 하는 경우
runuser -u elasticsearch -- '/usr/share/elasticsearch/bin/elasticsearch'

elasticsearch vm 관련 에러

wsl -d docker-desktop
echo "vm.max_map_count = 262144" >> /etc/sysctl.conf

이렇게 하고, container 를 새롭게 생성하자.

[컴] logstash 설정

로그스태시 / 설정

logstash 설정

2종류의 configuration file (ref. 1 참고)

  • pipeline config file : logstash 의 processing pipeline
    • deb 와 rpm 으로 설치한 경우
      • pipeline configuration file 들은 /etc/logstash/conf.d/에 있게 된다.
      • logstash 는 /etc/logstash/conf.d/*.conf 를 load 한다.
  • settings file : logstash 의 시작과 실행을 조정
    • logstash.yml
    • pipelines.yml
    • jvm.options
    • log4j2.properties
    • startup.options (Linux)
    • deb 와 rpm 으로 설치한 경우 /etc/logstash/ 에 있다.
      • /etc/logstash/logstash.yml

pipeline config file 사용법

  • deb, rpm 으로 설치한 경우 logstash path : /usr/share/logstash/bin/logstash
  • logstash-mine.conf 를 만든다.
  • bin/logstash -f logstash-mine.conf 를 하면 된다.
    • production 에서는 conf path 를 logstash.yml 에 정의하면 된다.
    • deb, rpm 에서는 /etc/logstash/conf.d/안의 *.conf 를 load 한다.
  • 아래처럼 3개의 section 으로 되어 있다.(input, filter, output)
  • 처리 부하가 다른 것들에 대한 처리를 위해 multiple pipeline 을 쓸 수 있다 : Introducing Multiple Pipelines in Logstash | Elastic Blog
# logstash-mine.conf


input { 
  stdin { }

}
filter {}
output {
  elasticsearch { hosts => ["localhost:9200"] }
  stdout { codec => rubydebug }
}

plugin 설정

각 section 에서 plugin 에 맞는 값을 넣게 된다. file 은 file plugin 을 이야기 하는 것이고, stdin 이라면 ‘logstash-input-stdin’ 을 이야기 하는 것이 된다. 이 값은 plugin list 를 확인하면 알 수 있다.

input {
  # 각 plugin 에 맞는 값을 넣게 된다. file 은 file plugin 을 이야기 하는 것이고, 
  # stdin 이라면 'logstash-input-stdin' 을 이야기 하는 것이 된다.
  # 이 값은 plugin list 를 확인하면 알 수 있다.
  file { # file plugin: logstash-input-file
    path => "/var/log/messages"
    type => "syslog"
  }

  file {
    path => "/var/log/apache/access.log"
    type => "apache"
  }
}

plugin list

확인방법 :

  • bin/logstash-plugin list 로 현재 설치된 plugin list 를 확인할 수 있다.
  • deb, rpm 으로 설치하면, 다음 path 에서 확인할 수 있다: /usr/share/logstash/bin/logstash-plugin
logstash-codec-avro
logstash-codec-cef
logstash-codec-collectd
logstash-codec-dots
logstash-codec-edn
logstash-codec-edn_lines
logstash-codec-es_bulk
logstash-codec-fluent
logstash-codec-graphite
logstash-codec-json
logstash-codec-json_lines
logstash-codec-line
logstash-codec-msgpack
logstash-codec-multiline
logstash-codec-netflow
logstash-codec-plain
logstash-codec-rubydebug
logstash-filter-aggregate
logstash-filter-anonymize
logstash-filter-cidr
logstash-filter-clone
logstash-filter-csv
logstash-filter-date
logstash-filter-de_dot
logstash-filter-dissect
logstash-filter-dns
logstash-filter-drop
logstash-filter-elasticsearch
logstash-filter-fingerprint
logstash-filter-geoip
logstash-filter-grok
logstash-filter-http
logstash-filter-json
logstash-filter-kv
logstash-filter-memcached
logstash-filter-metrics
logstash-filter-mutate
logstash-filter-prune
logstash-filter-ruby
logstash-filter-sleep
logstash-filter-split
logstash-filter-syslog_pri
logstash-filter-throttle
logstash-filter-translate
logstash-filter-truncate
logstash-filter-urldecode
logstash-filter-useragent
logstash-filter-uuid
logstash-filter-xml
logstash-input-azure_event_hubs
logstash-input-beats
└── logstash-input-elastic_agent (alias)
logstash-input-couchdb_changes
logstash-input-dead_letter_queue
logstash-input-elasticsearch
logstash-input-exec
logstash-input-file
logstash-input-ganglia
logstash-input-gelf
logstash-input-generator
logstash-input-graphite
logstash-input-heartbeat
logstash-input-http
logstash-input-http_poller
logstash-input-imap
logstash-input-jms
logstash-input-pipe
logstash-input-redis
logstash-input-s3
logstash-input-snmp
logstash-input-snmptrap
logstash-input-sqs
logstash-input-stdin
logstash-input-syslog
logstash-input-tcp
logstash-input-twitter
logstash-input-udp
logstash-input-unix
logstash-integration-elastic_enterprise_search
 ├── logstash-output-elastic_app_search
 └──  logstash-output-elastic_workplace_search
logstash-integration-jdbc
 ├── logstash-input-jdbc
 ├── logstash-filter-jdbc_streaming
 └── logstash-filter-jdbc_static
logstash-integration-kafka
 ├── logstash-input-kafka
 └── logstash-output-kafka
logstash-integration-rabbitmq
 ├── logstash-input-rabbitmq
 └── logstash-output-rabbitmq
logstash-output-cloudwatch
logstash-output-csv
logstash-output-elasticsearch
logstash-output-email
logstash-output-file
logstash-output-graphite
logstash-output-http
logstash-output-lumberjack
logstash-output-nagios
logstash-output-null
logstash-output-pipe
logstash-output-redis
logstash-output-s3
logstash-output-sns
logstash-output-sqs
logstash-output-stdout
logstash-output-tcp
logstash-output-udp
logstash-output-webhdfs
logstash-patterns-core

docker 에서 logstash

docker 에서 logstash 를 사용하는 경우, systemctl 을 사용하지 못하기 때문에 아무리 rpm 이나 deb 로 설치했다고 해도 systemctl 로 logstash 를 시작할 수 없다.

그리고 아래 경로에서도 확인되지만, /usr/share/logstash/config/logstash.yml 가 필요하다.

docker rockylinux image 에서 dnf install logstash 로 설치한 후에 /usr/share/logstash/bin/logstash 를 실행했는데, /etc/logstash/logstash.yml 이 존재함에도 인식하지 못했다. 그래서 /etc/logstash/logstash.yml/usr/share/logstash/config/logstash.yml 로 옮겼다.

그리고 그 후 *.conf/usr/share/logstash/config/conf.d 를 사용하지 않고, /etc/logstash/conf.d 에서 .conf 를 불러왔다.(logstash.yml 에 따로 path.confg를 설정해 놓지 않았다.)

ELK stack

beat 로 각 node 에서 logstash 로 정보를 던지고, logstash 가 그정보를 받아서 처리하고, elasticsearch 로 insert 시키게 하면 된다.

각 node 에 logstash 를 깔고 직접 elasticsearch 로 보내도 될 것 같지만, 그러면 부하가 있을 듯 싶긴 하다.

┌──────────────────┐        ┌───────────────────────────────────────┐
│                  │        │                                       │
│                  ├─────┬──┤► logstash --- elasticsearch --kibana  │
│ Beat             │     │  │                                       │
│ FileBeat,...     │     │  │                                       │
│                  │     │  │                                       │
└──────────────────┘     │  └───────────────────────────────────────┘
                         │
 ┌──────────────────┐    │
 │                  ├────┘
 │  Beat            │
 │  FileBeat,...    │
 │                  │
 └──────────────────┘
 ...

See Also

  1. 쿠…sal: [컴] IntelliJ에서 logstash source project 설정, 디버깅 환경 설정 - 1

References

  1. Configuring Logstash | Logstash Reference [8.2] | Elastic
  2. Structure of a config file | Logstash Reference [8.2] | Elastic

[컴] bitbucket 에서 app password 설정 방법

bitbucket 에서 app 암호 설정 / oauth / password 설정 / bitbucket git 암호 설정

bitbucket 에서 app password 설정 방법

여기서 생성된 암호는 다시 확인할 수 없으니, 잘 적어두자. 이때 account id 는 자신의 account id 를 사용하면 된다.

[컴][js] plain js 로 만든 간단한 rest api call functions

간단 / 바닐라 / vanila js / javascript fetch / my own / plain js request

plain js 로 만든 간단한 rest api call functions

  • timeout 부분만 추가됐다.
  • GET, POST 가 일관되게 data 를 사용하도록 했다.

사용법:

try{
    const res = await api.req.get({
      url: api.url.logout,        
    })
    window.location.href = "/"
} catch(e){
    console.error(e)
} finally {
    // this.isLoading = false
}

구현:

const req = {}

req._base = async function ({ url, method, headers, data, timeout }) {
  // for timeout
  const controller = new AbortController()
  const timeoutId = setTimeout(() => controller.abort(), timeout || 15000)

  // param
  const fetchParam = {
    method,
    headers,
    signal: controller.signal,
  }

  const { qstring, body } = _handleData(method, data)

  let realUrl = url
  if (qstring) {
    realUrl = `${url}?${qstring}`
  }

  if (body) {
    fetchParam.body = JSON.stringify(data)
  }

  try {
    /**
     * @return 
     *   {
     *     "content": [
     *       {
     *         ...
     *       },
     *       ...
     *     ]
     *     "message": "ok",
     *     "code": 0
     *   }
     */
    const resp = await fetch(realUrl, fetchParam)
    const respJson = await resp.json()
    if (!resp.ok) {
      // HTTP-status is 200-299
      const errorText = {
        status: resp.status,
        statusText: resp.statusText,
        respJson
      }
      throw new Error(`${JSON.stringify(errorText)}`)
    }

    return respJson

  } catch (err) {
    console.error('fetch error', err)
    throw err
  }
}

/**
 * @param {string} url @see the apis.url
 * @param {object} param 
 * @param {number} timeout in milliseconds
 */
req.get = async function ({ url, data, timeout }) {

  const respJson = await req._base({
    url,
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
    },
    data,
    timeout
  })
  return respJson

}

req.post = async function ({ url, data, timeout }) {

  const respJson = await req._base({
    url: url,
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    data,
    timeout
  })

  return respJson

}

req.patch = async function ({ url, data, timeout }) {

  const respJson = await req._base({
    url: url,
    method: 'PATCH',
    headers: {
      'Content-Type': 'application/json',
    },
    data,
    timeout
  })

  return respJson

}

req.delete = async function ({ url, data, timeout }) {

  const respJson = await req._base({
    url: url,
    method: 'DELETE',
    headers: {
      'Content-Type': 'application/json',
    },
    data,
    timeout
  })

  return respJson

}

function _handleData(method, data) {
  if (!data) {
    return {
      qstring: null,
      body: null,
    }
  }

  if (method.toUpperCase() == "GET") {
    const qstring = new URLSearchParams(data)
    return {
      qstring,
      body: null,
    }
  }
  return {
    qstring: null,
    body: JSON.stringify(data)
  }
}

module.exports = {
  url,
  pageUrl,
  req
}

[컴][swe]개발자 번아웃을 하게 하는 요소

burnout / burn out / developer / 리서치 조사 /

개발자 번아웃을 하게 하는 요소

  • 기관 : 세일즈포스 산하의 앱 통합 기업 ’뮬소프트(MuleSoft)’가 ’밴스 본(Vanson Bourne)’과 함께 시행
  • 설문조사 대상 : 600명에 달하는 CIO와 IT 의사 결정권자
  1. 증가하는 다른팀으로부터의 일/요구, 15%
  2. 디지털 전환 압박, 13%
  3. 기술 부족, 13%
  4. 주요 우선순위 밖의 증가하는 매일의 문제를 처리하는 것, 13%
  5. 빠르고 충분한 새로운 고용의 어려움, 10%
  6. 자동화할 수 있는 반복적인 일, 10%
  7. 적용할 새로운 technologies 과 새루운 접근법에 대한 새 skill들을 익히는것, 9%
  8. 혁신에 투자하기에 충분하지 않은 시간, 9%
  9. tooling 과 느린 개발 사이에 제한된 상호연동성(interoperability)
  10. 내가 아는 이유가 없다, 2%
  11. 기타 0%

개발자가 감당해야 하는 여러 가지 형태의 ’부담을 덜어주는 것’이 문제 해결을 위한 첫걸음이라는 것

References

  1. “채용난 이유 있다, 개발자 번아웃 주요 요인은…” 뮬소프트 조사 - CIO Korea, 2022-04-20
  2. New Research Shows How to Keep Developers Happy Amid the ‘Great Resignation’ - Salesforce News

[컴] jmeter 로 http request test 해보기

hello world / jmeter / test / test plan

jmeter 로 http request test 해보기

  1. File -> Templates
  2. ‘Building a Web Test Plan’ 선택 –> Create 버튼 클릭
  3. Test Plan 에서 마우스 오른쪽버튼 -> Add -> Listener -> Summary Report
    • 이것을 추가해야 summary 에 대한 정보를 볼 수 있다.
  4. 간단한 테스트를 위해 ‘Home Page’, ‘ThinkTime1s’ Sampler 들은 disable
  5. Run -> Start : 테스트를 시작한다.
  6. ‘View Results Tree’ 에서 테스트 결과를 볼 수 있다.
  7. Run -> Clear All(Ctrl + E) 하면 기록들이 다 지워진다.(log나 결과등)

See Also

  1. 쿠…sal: [컴][swe] Jmeter
  2. https://github.com/alexandrehtrb/Pororoca : postman 에서 영감받은 http request test tool

screenshots

[컴][swe] Jmeter

테스트툴

Jmeter

환경

  • windows 10

download

run in gui mode

<jmeter-home>/bin/jmeter.bat 를 실행하면 된다.

GUI mode 는 script 만들때 사용, load test 를 할 때는 CLI 모드를 사용 [ref. 1]

setenv.bat<jmeter-home>/bin 에 존재하면 setenv.bat를 실행해 준다. 다음처럼 setenv.bat를 생성했다. 이외에도 필요한 환경변수는 setenv.bat에 넣으면 된다.

rem setenv.bat
set JAVA_HOME=d:\a\apps\java\openjdk-jdk-15.0.1
set PATH=%PATH%;%JAVA_HOME%\bin

rem jmeter 실행시에 쓰이는 변수를 override 할 수 있다.
set JVM_ARGS=-Xms1024m -Xmx1024m -Dpropname=value

test 생성

  • ref. 2 의 Thread Group 참고
  • ’Test Plan’에서 원하는 element 를 추가할 수 있는데, ’template’은 이 element 를 어느정도 set 해놓은 상황이다.

Test Plan Element 들

  • jMeter - Test Plan Elements

  • JMeter Test Plan 은 test element 들로 구성된다.

  • 적어도 하나의 Thread Group 으로 구성된다.

  • 각 Thread Group 에서, 하나 이상의 다른 element 들의 조합을 놓을 것이다.(Sampler, Logic Controller, Configuration Element, Listener, and Timer)

  • Pre-processor element --> Sampler --> Post-Processor element + Assertion element 순서로 실행된다.

Thread Group

  • sample error 가 발생한 후 thread 를 stop 할지, test 를 stop 할지, 계속진행할지에 대한 판단 가능
  • thread 개수 : user수, 즉 연결수를 simulate 하는 것으로 보면 된다.
  • 확장 시간(ramp-up time) : JMeter 가 모든 thread들을 running 하게 만들기 위해 최소 얼마나 시간이 걸리게 할 것인지. 이 값이 크면 천천히 전체 thread 개수를 running 을 하는 것이 천천히 이뤄진다?
  • Loop count : 테스트를 실행하는 회수
  • 스케쥴러 설정 : test 를 실행하는 시간, 끝나는 시간을 설정할 수 있다.

Contorllers

다음 2가지가 있다.

  • Samplers
  • Logic Controllers

Samplers

  • sample 을 만드는 녀석이라고 보면 된다.
  • 특정 type 의 request 를 서버에게 보내게 해준다.
  • page 를 위한 user request 를 시뮬레이한다. 예를 들어 HTTP service 의 POST, GET, DELETE 등을 수행할 때는 HTTP Request sampler 를 추가할 수 있다.
  • HTTP, FTP, JDBC, Java, SOAP/XML, RPC request 들에 대한 sampler 가 있다.

Logic Controllers

request 를 반복시키거나, 특정 조건에서 돌게 하거나 등의 처리를 할 수 있다.

  • Logic Controllers는 Thread 에서 Samplers 의 처리 순서를 제어할 수 있게 해준다.
  • Logic Controllers는 child elements 에서 오는 request 의 순서를 변경할 수 있다.
  • controller 들
    • Simple Controller
    • Loop Controller
    • Once Only Controller
    • Interleave Controller
    • Random Controller
    • Random Order Controller
    • Throughput Controller
    • Runtime Controller
    • If Controller
    • While Controller
    • Switch Controller
    • ForEach Controller
    • Module Controller
    • Include Controller
    • Transaction Controller
    • Recording Controller

Test Framgments

  • Test Fragments 는 Module Contorller 또는 Include_Controller 에 의해 referenced 되지 않으면 수행되지 않는다라는 점에서 Thread Group 과는 다르다
  • 이 element 는 Test Plans 내에서 오직 code 재사용을 위해 쓰인다

Listeners

  • Listener들은 Sampler들의 결과를 보여준다. tables , 그래프, 트리, log file 의 간단한 test 등의 형태로.
  • JMeter의 Sampler component 가 수행될때, JMeter 에 의해 모아진 test case에 대한 데이터에 대한 접근 비쥬얼적인 접근을 제공한다.
  • test 의 어느곳에나 추가될 수 있다.
  • 그들의 level 이하의 elemnt 들에게서 나오는 data만을 모은다.
  • JMeter 가 제공하는 모든 Listener들
    • Sample Result Save Configuration
    • Graph Full Results
    • Graph Results
    • Spline Visualizer
    • Assertion Results
    • View Results Tree
    • Aggregate Report
    • View Results in Table
    • Simple Data Writer
    • Monitor Results
    • Distribution Graph (alpha)
    • Aggregate Graph
    • Mailer Visualizer
    • BeanShell Listener
    • Summary Report

그외

  • Timers
  • Assertions
  • Configuration Elements : Sampler 에서 사용되는 변수를 만들게 해준다.
  • Pre-processor Elements
  • Post-processor Elements
  • Execution Order of Test Elements

Best Practices

JMeter는 특히 분산 환경에서 실행되는 경우 몇 가지 제한이 있다. 이 가이드는 실제적이고 연속적인 부하(load)를 생성하는 데 도움이 된다.

  • 스레드 수가 많을 경우 JMeter를 여러개 실행해서 사용
  • Scoping Rules 를 체크하고 그에 따라 design
  • 모든 elements에 항상 naming convetion을 사용
  • 스크립트를 실행하기 전에 기본 브라우저의 연결 설정(Connectivity Settings)을 확인
  • Listeners를 적절하게 추가.
  • 다음은 리소스 요구사항을 줄이기 위한 방법
    • non-GUI 모드(jmeter -n -t test.jmx -l test.jtl) 사용
    • Listener를 최대한 적게 사용. 위와 같이 -l 플래그를 사용하는 경우 Listener를 모두 삭제하거나 비활성화할 수 있다.
    • “View Result Tree” Listener는 메모리를 많이 소모한다. 콘솔이 중지되거나 JMeter의 메모리가 부족해질 수 있으므로 사용하지 않도록 설정한다. 그러나 “Errors”만 선택한 상태에서 “View Result Tree” Listener를 사용하는 것은 괜찮다.
    • 유사한 Sampler를 많이 사용하는 대신 loop에서 same sampler와 변수(CSV 데이터 세트)를 사용하여 sample을 다양하게 변경하자. 또는 Access Log Sampler 를 사용하자.
    • functional mode를 사용하지 마십시오.
    • XML 대신 CSV 출력을 사용.
    • 필요한 데이터만 저장.
    • 가능한 한 적은 수의 Assertions를 사용.
    • 모든 JMeter 그래프는 메모리를 많이 사용하므로 사용하지 않도록 설정. 웹 인터페이스의 JTL 탭을 사용하여 모든 실시간 그래프를 볼 수 있다.
    • CSV Data Set Config(CSV 데이터 세트 구성)에서 local path를 지우는 것을 잊지 마라.
    • 모든 테스트 실행 전에 Files tab을 비우자

Reference

  1. Apache JMeter - User’s Manual: Getting Started
  2. jMeter - Quick Guide
  3. jMeter - Best Practices