├── .gitignore ├── tests ├── commands_test.sh └── assert.sh ├── Makefile ├── .travis.yml ├── LICENSE ├── CONTRIBUTING.md ├── CODE_OF_CONDUCT.md ├── README.md └── memcache-info /.gitignore: -------------------------------------------------------------------------------- 1 | /nbproject/* -------------------------------------------------------------------------------- /tests/commands_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export GREP="grep" 4 | . tests/assert.sh -v 5 | 6 | src="./memcache-info" 7 | 8 | assert_raises "$src" 0 9 | assert_contains "$src -h" "memcache-info" 10 | assert_contains "$src" "Memcache Stats" 11 | assert_contains "$src" "Time info" 12 | assert_contains "$src" "Connection info" 13 | assert_contains "$src" "Get info" 14 | assert_contains "$src" "Delete info" 15 | assert_contains "$src" "Memory info" 16 | assert_contains "$src -r" "Memory info" 17 | assert_contains "$src -p 11211" "Memory info" 18 | assert_contains "$src -n localhost" "Memory info" 19 | assert_contains "$src -n localhost -p 11211" "Memory info" 20 | 21 | assert_end -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | prefix=/usr/local 2 | TASK_DONE = echo "\n✓ $@ done\n" 3 | # files that need mode 755 4 | EXEC_FILES=memcache-info 5 | 6 | .PHONY: test 7 | 8 | all: 9 | @echo "usage: make install" 10 | @echo " make uninstall" 11 | @echo " make reinstall" 12 | @echo " make test" 13 | 14 | help: 15 | $(MAKE) all 16 | @$(TASK_DONE) 17 | 18 | install: 19 | install -m 0755 $(EXEC_FILES) $(prefix)/bin 20 | @$(TASK_DONE) 21 | 22 | uninstall: 23 | test -d $(prefix)/bin && \ 24 | cd $(prefix)/bin && \ 25 | rm -f $(EXEC_FILES) 26 | @$(TASK_DONE) 27 | 28 | reinstall: 29 | git pull origin master 30 | $(MAKE) uninstall && \ 31 | $(MAKE) install 32 | @$(TASK_DONE) 33 | 34 | test: 35 | tests/commands_test.sh 36 | @$(TASK_DONE) -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: generic 2 | 3 | sudo: required 4 | 5 | addons: 6 | apt: 7 | packages: 8 | - libcurl4-openssl-dev 9 | - libelf-dev 10 | - libdw-dev 11 | - cmake 12 | 13 | services: memcache 14 | env: MEMCACHED__HOST=localhost 15 | 16 | install: 17 | - git checkout ${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} 18 | - git branch --set-upstream-to origin/$TRAVIS_BRANCH 19 | - git rev-parse HEAD 20 | 21 | script: make test 22 | 23 | after_success: | 24 | wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz && 25 | tar xzf master.tar.gz && 26 | cd kcov-master && 27 | mkdir build && 28 | cd build && 29 | cmake .. && 30 | make && 31 | sudo make install && 32 | cd ../.. && 33 | rm -rf kcov-master && 34 | mkdir -p coverage && 35 | kcov coverage memcache-info && 36 | bash <(curl -s https://codecov.io/bash) -cF firstrun && 37 | kcov coverage memcache-info -h && 38 | bash <(curl -s https://codecov.io/bash) -cF usage -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Hyperia s.r.o. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | Want to contribute? Great! First, read this page. 5 | 6 | # Code reviews 7 | All submissions, including submissions by project members, require review. We 8 | use Github pull requests for this purpose. 9 | 10 | # Some tips for good pull requests: 11 | * Use our code 12 | When in doubt, try to stay true to the existing code of the project. 13 | * Write a descriptive commit message. What problem are you solving and what 14 | are the consequences? Where and what did you test? Some good tips: 15 | [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message) 16 | and [here](https://www.kernel.org/doc/Documentation/SubmittingPatches). 17 | * If your PR consists of multiple commits which are successive improvements / 18 | fixes to your first commit, consider squashing them into a single commit 19 | (`git rebase -i`) such that your PR is a single commit on top of the current 20 | HEAD. This make reviewing the code so much easier, and our history more 21 | readable. 22 | 23 | # Formatting 24 | 25 | This documentation is written using standard [markdown syntax](https://help.github.com/articles/markdown-basics/). Please submit your changes using the same syntax. 26 | 27 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at info@hyperia.sk. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Memcache Simple Info 2 | 3 | [![Build Status](https://travis-ci.org/hyperia-sk/memcache-info.svg?branch=master)](https://travis-ci.org/hyperia-sk/memcache-info) [![codecov](https://codecov.io/gh/hyperia-sk/memcache-info/branch/master/graph/badge.svg)](https://codecov.io/gh/hyperia-sk/memcache-info) 4 | 5 | > `memcache-info` is a simple and efficient way to show info about Memcache. 6 | 7 | ![screenshot](https://user-images.githubusercontent.com/6382002/31081331-d382066e-a78b-11e7-8979-cd3faf33629b.png) 8 | 9 | ## Usage 10 | 11 | ```bash 12 | memcache-info 13 | ``` 14 | 15 | or execute periodicaly `watch --interval=1 "memcache-info -r"` 16 | 17 | #### Parameters 18 | 19 | ```bash 20 | memcache-info [ -n | -p | -h | -r ] 21 | 22 | -n 23 | Name of the host or IP address (default: 127.0.0.1). 24 | 25 | -p 26 | Port number (default: 11211). 27 | 28 | -h 29 | Prints this help. 30 | 31 | -r 32 | Disable interpret ANSI color and style sequences. (default: 0) 33 | ``` 34 | 35 | ## Installation 36 | 37 | ```bash 38 | git clone https://github.com/hyperia-sk/memcache-info.git && cd memcache-info 39 | ``` 40 | 41 | Open up the cloned directory and run: 42 | 43 | #### Unix like OS 44 | 45 | ```bash 46 | sudo make install 47 | ``` 48 | 49 | For uninstalling 50 | 51 | ```bash 52 | sudo make uninstall 53 | ``` 54 | 55 | For update/reinstall 56 | 57 | ```bash 58 | sudo make reinstall 59 | ``` 60 | 61 | #### OS X (homebrew) 62 | 63 | @todo 64 | 65 | #### Windows (cygwin) 66 | 67 | @todo 68 | 69 | 70 | ## System requirements 71 | 72 | * Unix like OS with a proper shell 73 | * Tools we use: nc ; mktemp ; basename ; seq ; bc ; awk ; tr ; printf 74 | 75 | 76 | ## Contribution 77 | 78 | Want to contribute? Great! First, read this page. 79 | 80 | #### Code reviews 81 | 82 | All submissions, including submissions by project members, require review. 83 | We use Github pull requests for this purpose. 84 | 85 | #### Some tips for good pull requests: 86 | * Use our code 87 | When in doubt, try to stay true to the existing code of the project. 88 | * Write a descriptive commit message. What problem are you solving and what 89 | are the consequences? Where and what did you test? Some good tips: 90 | [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message) 91 | and [here](https://www.kernel.org/doc/Documentation/SubmittingPatches). 92 | * If your PR consists of multiple commits which are successive improvements / 93 | fixes to your first commit, consider squashing them into a single commit 94 | (`git rebase -i`) such that your PR is a single commit on top of the current 95 | HEAD. This make reviewing the code so much easier, and our history more 96 | readable. 97 | 98 | #### Formatting 99 | 100 | This documentation is written using standard [markdown syntax](https://help.github.com/articles/markdown-basics/). Please submit your changes using the same syntax. 101 | 102 | #### Tests 103 | 104 | ```bash 105 | make test 106 | ``` 107 | 108 | ## Licensing 109 | MIT see [LICENSE][] for the full license text. 110 | 111 | [read this page]: https://github.com/hyperia-sk/memcache-info/blob/master/CONTRIBUTING.md 112 | [landing page]: https://github.com/hyperia-sk/memcache-info 113 | [LICENSE]: https://github.com/hyperia-sk/memcache-info/blob/master/LICENSE 114 | 115 | 116 | -------------------------------------------------------------------------------- /tests/assert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # assert.sh 1.1 - bash unit testing framework 3 | # Copyright (C) 2009-2015 Robert Lehmann 4 | # 5 | # http://github.com/lehmannro/assert.sh 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published 9 | # by the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | export DISCOVERONLY=${DISCOVERONLY:-} 21 | export DEBUG=${DEBUG:-} 22 | export STOP=${STOP:-} 23 | export INVARIANT=${INVARIANT:-} 24 | export CONTINUE=${CONTINUE:-} 25 | 26 | args="$(getopt -n "$0" -l \ 27 | verbose,help,stop,discover,invariant,continue vhxdic $*)" \ 28 | || exit -1 29 | for arg in $args; do 30 | case "$arg" in 31 | -h) 32 | echo "$0 [-vxidc]" \ 33 | "[--verbose] [--stop] [--invariant] [--discover] [--continue]" 34 | echo "`sed 's/./ /g' <<< "$0"` [-h] [--help]" 35 | exit 0;; 36 | --help) 37 | cat < [stdin] 102 | (( tests_ran++ )) || : 103 | [[ -z "$DISCOVERONLY" ]] || return 104 | expected=$(echo -ne "${2:-}") 105 | result="$(eval 2>/dev/null $1 <<< ${3:-})" || true 106 | if [[ "$result" == "$expected" ]]; then 107 | [[ -z "$DEBUG" ]] || echo -n . 108 | return 109 | fi 110 | result="$(sed -e :a -e '$!N;s/\n/\\n/;ta' <<< "$result")" 111 | [[ -z "$result" ]] && result="nothing" || result="\"$result\"" 112 | [[ -z "$2" ]] && expected="nothing" || expected="\"$2\"" 113 | _assert_fail "expected $expected${_indent}got $result" "$1" "$3" 114 | } 115 | 116 | assert_raises() { 117 | # assert_raises [stdin] 118 | (( tests_ran++ )) || : 119 | [[ -z "$DISCOVERONLY" ]] || return 120 | status=0 121 | (eval $1 <<< ${3:-}) > /dev/null 2>&1 || status=$? 122 | expected=${2:-0} 123 | if [[ "$status" -eq "$expected" ]]; then 124 | [[ -z "$DEBUG" ]] || echo -n . 125 | return 126 | fi 127 | _assert_fail "program terminated with code $status instead of $expected" "$1" "$3" 128 | } 129 | 130 | # _assert_with_grep 131 | _assert_with_grep() { 132 | local grep_modifier="$1" 133 | local output="$($2)" 134 | local exitcode="$4" || 0 135 | shift 2 136 | 137 | while [ $# != 0 ]; do 138 | assert_raises "echo \"$output\" | $GREP $grep_modifier '$1'" $exitcode || return 1 139 | shift 140 | done 141 | } 142 | 143 | # assert_startswith 144 | assert_startswith() { 145 | assert_success "[[ '$($1)' == '$2'* ]]" 146 | } 147 | 148 | # assert_endswith 149 | assert_endswith() { 150 | assert_success "[[ '$($1)' == *'$2' ]]" 151 | } 152 | 153 | # assert_contains 154 | assert_contains() { 155 | _assert_with_grep '-F' "$@" 156 | } 157 | 158 | _assert_fail() { 159 | # _assert_fail 160 | [[ -n "$DEBUG" ]] && echo -n X 161 | report="test #$tests_ran \"$2${3:+ <<< $3}\" failed:${_indent}$1" 162 | if [[ -n "$STOP" ]]; then 163 | [[ -n "$DEBUG" ]] && echo 164 | echo "$report" 165 | exit 1 166 | fi 167 | tests_errors[$tests_failed]="$report" 168 | (( tests_failed++ )) || : 169 | } 170 | 171 | skip_if() { 172 | # skip_if 173 | (eval $@) > /dev/null 2>&1 && status=0 || status=$? 174 | [[ "$status" -eq 0 ]] || return 175 | skip 176 | } 177 | 178 | skip() { 179 | # skip (no arguments) 180 | shopt -q extdebug && tests_extdebug=0 || tests_extdebug=1 181 | shopt -q -o errexit && tests_errexit=0 || tests_errexit=1 182 | # enable extdebug so returning 1 in a DEBUG trap handler skips next command 183 | shopt -s extdebug 184 | # disable errexit (set -e) so we can safely return 1 without causing exit 185 | set +o errexit 186 | tests_trapped=0 187 | trap _skip DEBUG 188 | } 189 | _skip() { 190 | if [[ $tests_trapped -eq 0 ]]; then 191 | # DEBUG trap for command we want to skip. Do not remove the handler 192 | # yet because *after* the command we need to reset extdebug/errexit (in 193 | # another DEBUG trap.) 194 | tests_trapped=1 195 | [[ -z "$DEBUG" ]] || echo -n s 196 | return 1 197 | else 198 | trap - DEBUG 199 | [[ $tests_extdebug -eq 0 ]] || shopt -u extdebug 200 | [[ $tests_errexit -eq 1 ]] || set -o errexit 201 | return 0 202 | fi 203 | } 204 | 205 | 206 | _assert_reset 207 | : ${tests_suite_status:=0} # remember if any of the tests failed so far 208 | _assert_cleanup() { 209 | local status=$? 210 | # modify exit code if it's not already non-zero 211 | [[ $status -eq 0 && -z $CONTINUE ]] && exit $tests_suite_status 212 | } 213 | trap _assert_cleanup EXIT -------------------------------------------------------------------------------- /memcache-info: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | 5 | white=$(tput bold) 6 | red=$(tput setaf 1) 7 | green=$(tput setaf 2) 8 | yellow=$(tput setaf 3) 9 | blue=$(tput setaf 6) 10 | normal=$(tput sgr0) 11 | readonly format="%-18s %-10s %-30s\n" 12 | subject="Memcache Stats" 13 | 14 | function logo() 15 | { 16 | echo "${blue} _ _ ${yellow}_${normal}" 17 | echo "${blue} | | | |_ _ _ __ ___ _ _${yellow}(_)${normal}${blue} __ _ ${normal}" 18 | echo "${blue} | |_| | | | | '_ \ / _ \ '_${yellow}| |${normal}${blue}/ _' |${normal}" 19 | echo "${blue} | _ | |_| | |_) | __/ | ${yellow}| |${normal}${blue} (_| |${normal}" 20 | echo "${blue} |_| |_|\__, | .__/ \___|_| ${yellow}|_|${normal}${blue}\__,_|${normal}" 21 | echo "${blue} |___/|_| ${normal}${white}$subject${normal}" 22 | } 23 | 24 | function usage() 25 | { 26 | logo 27 | cat < 33 | Name of the host or IP address (default: 127.0.0.1). 34 | 35 | -p 36 | Port number (default: 11211). 37 | 38 | -h 39 | Prints this help. 40 | 41 | -r 42 | Disable interpret ANSI color and style sequences. (default: 1) 43 | 44 | EOF 45 | exit $1 46 | } 47 | 48 | OPTERR=0 49 | PORT="11211" 50 | HOST_NAME="127.0.0.1" 51 | COLOR=1 52 | while getopts ":n:p:h:r" options 53 | do 54 | case $options in 55 | n) 56 | HOST_NAME=$OPTARG 57 | ;; 58 | p) 59 | PORT=$OPTARG 60 | ;; 61 | r) 62 | COLOR=0 63 | ;; 64 | h|*) 65 | usage 0 66 | ;; 67 | esac 68 | done 69 | shift $(($OPTIND - 1)) 70 | 71 | 72 | function _echo 73 | { 74 | printf '%s\n' "$1" 75 | } 76 | 77 | slabStats=$(mktemp) 78 | _echo "stats slabs" | nc -q 1 $HOST_NAME $PORT > $slabStats || (_echo "${red}Connect to $HOST_NAME:$PORT failed.${normal}" && exit 1) 79 | 80 | stats=$(mktemp) 81 | _echo "stats" | nc -q 1 $HOST_NAME $PORT > $stats 82 | 83 | function isInteger() 84 | { 85 | [[ ${1} == ?(-)+([0-9]) ]] 86 | } 87 | 88 | function _echoB 89 | { 90 | _echo "" 91 | 92 | if [[ $COLOR == 1 ]]; then 93 | _echo "${white}$1${normal}" 94 | else 95 | _echo "$1" 96 | fi 97 | 98 | _echo "" 99 | } 100 | 101 | scale=2 102 | function _calc 103 | { 104 | _echo "scale=$scale; $@" | bc -l | sed 's/^\./0./' 105 | } 106 | 107 | function _drawSparkLine 108 | { 109 | chart="█"; 110 | scale=1 111 | fragPercent=0 112 | 113 | if [ "$2" -gt "0" ]; then 114 | percent=$(_calc "(($1/$2)*100)/5" ); 115 | for i in `seq 1 $percent` 116 | do 117 | chart=$chart"█" 118 | done 119 | 120 | scale=2 121 | fragPercent=$(_calc 100*$1/$2) 122 | fi 123 | 124 | _echo $chart" ($fragPercent%)" 125 | } 126 | 127 | function getStatsInfo() 128 | { 129 | cat $stats | grep "STAT $1" | awk '{ print $3 }' | tr -d '\r' 130 | } 131 | 132 | function getLimitMaxBytes() 133 | { 134 | cat $stats | grep "STAT limit_maxbytes" | awk '{ print $3}' | tr -d '\r' 135 | } 136 | 137 | function getSlabInfo() 138 | { 139 | cat $slabStats | grep "STAT $1:$2" | awk '{ print $3}' | tr -d '\r' 140 | } 141 | 142 | function getTotalMemory() 143 | { 144 | cat $slabStats | grep "STAT total_malloced" | awk '{ print $3}' | tr -d '\r' 145 | } 146 | 147 | function getSlabMemoryUsed() 148 | { 149 | getSlabInfo $1 "mem_requested" 150 | } 151 | 152 | function getSlabMemoryWasted() 153 | { 154 | totalChunks=$( getSlabInfo $1 "total_chunks") 155 | usedChunks=$( getSlabInfo $1 "used_chunks") 156 | chunkSize=$( getSlabInfo $1 "chunk_size") 157 | memRequested=$( getSlabMemoryUsed $1 ) 158 | 159 | if isInteger $memRequested; then 160 | totalChunksSize=$( _echo "$totalChunks * $chunkSize" | bc) 161 | if [ "$totalChunksSize" -lt "$memRequested" ]; then 162 | memoryWasted=$( _echo "($totalChunks - $usedChunks) * $chunkSize" | bc ) 163 | else 164 | memoryWasted=$( _echo "$totalChunks * $chunkSize - $memRequested" | bc ) 165 | fi 166 | fi 167 | 168 | _echo $memoryWasted 169 | } 170 | 171 | function getTotalMemoryUsed() 172 | { 173 | numberOfSlabs=$( cat $slabStats | grep "STAT active_slabs" | awk '{ print $3}' | tr -d '\r' ) 174 | totalMemoryUsed=0 175 | 176 | for i in `seq 1 $numberOfSlabs`; 177 | do 178 | memoryUsed=$( getSlabMemoryUsed $i ) 179 | if isInteger $memoryUsed; then 180 | totalMemoryUsed=$( _echo "$totalMemoryUsed + $memoryUsed" | bc ) 181 | fi 182 | done 183 | 184 | _echo $totalMemoryUsed 185 | } 186 | 187 | function getTotalMemoryWasted() 188 | { 189 | numberOfSlabs=$( cat $slabStats | grep "STAT active_slabs" | awk '{ print $3}' | tr -d '\r' ) 190 | totalMemoryWasted=0 191 | 192 | for i in $(seq 1 $numberOfSlabs); 193 | do 194 | memoryWasted=$( getSlabMemoryWasted $i ) 195 | if isInteger $memoryWasted; then 196 | totalMemoryWasted=$( _echo "$totalMemoryWasted + $memoryWasted" | bc ) 197 | fi 198 | done 199 | 200 | _echo $totalMemoryWasted 201 | } 202 | 203 | function main() 204 | { 205 | logo 206 | _echo "" 207 | 208 | printf "$format" "Version" "$(getStatsInfo "version")" 209 | printf "$format" "PID" $(getStatsInfo "pid") 210 | uptime=$(getStatsInfo "uptime") 211 | printf "$format" "Uptime" "~"$(_calc $uptime/86400)" days ($uptime sec.)" 212 | scale=0 213 | printf "$format" "Total items" $(getStatsInfo "curr_items") 214 | printf "$format" "Set requests" $(getStatsInfo "cmd_set") 215 | printf "$format" "Flush requests" $(getStatsInfo "cmd_flush") 216 | 217 | _echoB "Time info" 218 | printf "$format" "User time" "$(date)" 219 | printf "$format" "Memcache time" "$(date --date="@$(getStatsInfo "time ")")" 220 | 221 | _echoB "Connection info" 222 | printf "$format" "Current" $(getStatsInfo "curr_connections") 223 | printf "$format" "Total" $(getStatsInfo "total_connections") 224 | 225 | _echoB "Get info" 226 | totalHits=$(getStatsInfo "get_hits") 227 | totalMisses=$(getStatsInfo "get_misses") 228 | totalRequests=$(_calc $totalHits+$totalMisses) 229 | scale=2 230 | printf "$format" "Requests" $totalRequests 231 | printf "$format" "Hits" "$totalHits" "$(_drawSparkLine $totalHits $totalRequests)" 232 | printf "$format" "Misses" "$totalMisses" "$(_drawSparkLine $totalMisses $totalRequests)" 233 | 234 | _echoB "Delete info" 235 | totalHits=$(getStatsInfo "delete_hits") 236 | totalMisses=$(getStatsInfo "delete_misses") 237 | totalRequests=$(_calc $totalHits+$totalMisses) 238 | printf "$format" "Requests" $totalRequests 239 | printf "$format" "Hits" "$totalHits" "$(_drawSparkLine $totalHits $totalRequests)" 240 | printf "$format" "Misses" "$totalMisses" "$(_drawSparkLine $totalMisses $totalRequests)" 241 | 242 | _echoB "Memory info" 243 | maxMemory=$( getLimitMaxBytes ) 244 | totalMemory=$( getTotalMemory ) 245 | totalMemoryPercent=$(_calc "($totalMemory / $maxMemory) * 100") 246 | totalMemoryUsed=$( getTotalMemoryUsed ) 247 | totalMemoryWasted=$( getTotalMemoryWasted ) 248 | freeMemory=$(_calc "$maxMemory - ($totalMemoryUsed + $totalMemoryWasted)" ) 249 | freeMemoryPercent=$(_calc "($freeMemory / $maxMemory) * 100" ) 250 | printf "$format" "Max memory" "$(_calc "($maxMemory)/1024/1024") MB" 251 | printf "$format" "Free" "$(_calc "($freeMemory)/1024/1024") MB" "$(_drawSparkLine $freeMemory $maxMemory)" 252 | printf "$format" "Total allocated" "$(_calc "($totalMemory)/1024/1024") MB" "$(_drawSparkLine $totalMemory $maxMemory)" 253 | printf "$format" " - used" "$(_calc "($totalMemoryUsed)/1024/1024") MB" 254 | printf "$format" " - wasted" "$(_calc "($totalMemoryWasted)/1024/1024") MB" 255 | 256 | _echo "" 257 | } 258 | 259 | if [[ $COLOR == 0 ]]; then 260 | white="" 261 | red="" 262 | green="" 263 | yellow="" 264 | blue="" 265 | normal="" 266 | fi 267 | 268 | main 269 | exit 270 | --------------------------------------------------------------------------------